Issues with fopen understanding the filepath I am giving it - matlab

Basically, I build a list of files using ls, then want to loop through that list, read in a file, and do some stuff. But when I try to read the file in it fails.
Here is an example
r=ls(['Event_2006_334_21_20_11' '/*.r'])
Event_2006_334_21_20_11/IU.OTAV_1.0.i.r
which is a 1x80 char
fopen(r(1,:))
-1
but
fopen('Event_2006_334_21_20_11/IU.OTAV_1.0.i.r')
12 (or whatever its on)
works. I've tried string(r) and char(r) and sprintf('%s',r). If I just build the string like r = ['Event_2006_334_21_20_11' '/IU.OTAV_1.0.i.r'] it works. So it seems something about combining the different variable types that messes it up but I can't seem to find a workaround. Probably something obvious I'm missing.
Any suggestions?

ls returns a matrix of characters, which means each row contains the same number of characters. To indicate the problem, try:
['-' r(1,:) '-']
You will probably notice some whitespaces in front of the -. Unless you want to print the output to the command line, ls is not really useful. As mentioned by Alex, use dir instead.
A further tip regarding your last comment, concatenate file path using fullfile. It makes sure you get one file separator whenever concatenating:
>> fullfile('myfolder','mysubfolder','myfile.m')
ans = myfolder/mysubfolder/myfile.m
>> fullfile('myfolder/','mysubfolder','myfile.m')
ans = myfolder/mysubfolder/myfile.m
>> fullfile('myfolder/','/mysubfolder','myfile.m')
ans = myfolder/mysubfolder/myfile.m

Related

Matlab - Help in listing files using a name-pattern

I'm trying to create a function that lists the content of a folder based on a pattern, however the listing includes more files than needed. I'll explain by an example: Consider a folder containing the files
file.dat
file.dat._
file.dat.000
file.dat.001
...
file.dat.999
I am interested only in the files that are .000, .001 and so on. The files file.dat and file.dat._ are to be excluded.
The later numbering can also be .0000,.0001 and so on, so number of digits is not necessarily 3.
I tried using the Dir command with the pattern file.dat.* - this included file.dat for some reason (Why the last comma treated differently?) and file.dat._, which was expected.
The "obvious" set of solutions is to add an additional regular expression or length check - however I would like to avoid that, if possible.
This needs to work both under UNIX and Windows (and preferably MacOS).
Any elegant solutions?
Get all filenames with dir and filter them using with the regex '^file\.dat\.\d+$'. This matches:
start of the string (^)
followed by the string file.dat. (file\.dat\.)
followed by one or more digits (\d+)
and then the string must end ($)
Since the output of dir is a cell array of char vectors, regex returns a cell array with the matching indices of each char vector. The matching indices can only be 1 or [], so any is applied to each cell's content to reduce it to true or false The resulting logical index tells which filenames should be kept.
f = dir('path/to/folder');
names = {f.name};
ind = cellfun(#any, regexp(names, '^file\.dat\.\d+$'));
names = names(ind);

MATLAB function importdata acting weird

I have a text file with numbers that looks like this:
a.txt
0.001240242769
-0.000829468827
-0.0001689229831
0.0008228798977
-3.86881172e-05
in a MATLAB I used to be able to use
x_in = importdata('a.txt');
and x_in was in fact a vector of 5 double numbers.
I don't know what I changed yesterday but all of a sudden when I use the same function it downloads as char
x_in='0.001240242769
-0.000829468827
-0.0001689229831
0.0008228798977
-3.86881172e-05'
What did I change and how can I fix it back?
The likely cause is that the text file has something that is not recognized as number or delimiter. I would suggest to use load as following:
x_in = load('a.txt', '-ascii');

How can I get a part of partfile?

This is probably a very simple question, but I am not able to find a straightforward solution.
[pathstr,name,ext] = fileparts('/xaaa/Data/Q2/CONUS/2002/PRECIPRATE.20020401.000000.tif')
Obviously, fileparts gives /xaaa/Data/Q2/CONUS/2002/
But I only want to access /xaaa/Data/Q2/CONUS/ and disregard the last section.
One way to do it is simply count the letters parthstr(1:20). But there must be an elegant alternative.
The most robust way to get a parent folder is to use '..' to access the folder above a provided folder. This is because it is independent of whether you specify an absolute or relative path as the input.
parent = fullfile(folder, '..');
In your case, since you have a filename and you want to get the parent, you can add a 'fileparts' call to that to get the direct parent folder, then pass it to the above.
parent = fullfile(fileparts(filename), '..');
This is more robust because it allows you to specify a relative file path such as 2002/PRECIPRATE.20020401.000000.tif which could fail if you tried to call fileparts multiple times.
If you only have a filename (with no directories because you're in the folder where the file is), you can use which to get an absolute path to the file.
parent = fullfile(fileparts(which(filename)), '..');
One simple way is to repeat the use of fileparts():
>> [pathstr,name,ext] = fileparts('/xaaa/Data/Q2/CONUS/2002/PRECIPRATE.20020401.000000.tif');
>> [parent_pathstr, name, ~] = fileparts(pathstr)
parent_pathstr =
/xaaa/Data/Q2/CONUS
name =
2002
Note: using the tilde ~ just ignores the file extension for the second call to fileparts() because you don't expect an extension.
There are three answers proposed already, but I do believe there's a better solution. I would match .*(?=/.*/) pattern using regexp, like this:
>> originalPath = '/xaaa/Data/Q2/CONUS/2002/PRECIPRATE.20020401.000000.tif';
>> res = char(regexp(originalPath, '.*(?=/.*/)', 'match'))
res =
/xaaa/Data/Q2/CONUS
If you need to go n levels deeper, just keep adding .*/ for each level, e.g.
>> res = char(regexp(originalPath, '.*(?=/.*/.*/)', 'match'))
res =
/xaaa/Data/Q2
For the OS-agnistic version, or if your path contains some mixture of back-slashes and forward-slashes, you can use the following regex: '.*(?=[/\\].*[/\\])'. Once again, to go several levels deper, just add an extra .*[/\\] for each level.
The benefit over using strsplit and fileparts is that you don't need to iterate anything - you get the answer with one simple regex.
Regarding .. - I myself used this solution for a long time for generating Matlab Path dynamically. However Matlab is sometimes not able to handle breakpoints correctly in the files that have .. in their path. To be exact, if you place a breakpoint in such a file, Matlab would ignore it unless there's another breakpoint that is triggered first (which is not in a file with .. in path).
It obviously handles relative paths as well.

Removing quotes that seem to be nonexistent in MatLab

I have an application that translates the .csv files I currently have into the correct format I need. But, the files I that I do have seem to have '"' double quotes around them, as seen in this image, which will not work with the program. As a result, I'm using this command to remove them:
for m = 1:currentsize(1)
for n = 1:currentsize(2)
replacement{m,n} = strrep(current{m,n}, '"', '');
end
end
I'm not entirely sure that this works though, as it spits this back at me as it runs:
Warning: Inputs must be character arrays or cell arrays of strings.
When I open the file in matlab, it seems to only have the single quotes around it, which is normal for any other file. However, when I open it in notepad++, it seems to have '"' double quotes around everything. Is there a way to remove these double quotes in any other way? My code doesn't seem to do anything as seen here:
After using xlswrite to write the replacement cell-array to a .csv file, one appears corrupted. Any idea why?
So, my questions are:
Is there any way to remove the quotes in a more efficient manner or without rewriting to a csv?
and
What exactly is causing the corruption in the xlswrite function? The variable replacement seems perfectly normal.
Thanks in advance!
Regarding the "corrupted" file. That's not a corrupted file, that's an xls file (not xlsx). You could verify this opening the text file in a hex editor to compare the signature. This happens when you chose no file extension or ask excel to write a file which can't be encoded into csv. I assume it's some character which causes the problems, try to isolate the critical line writing only parts of the cell.
Regarding your warning, not having the actual input I could only guess what's wrong. Again, I can only give some advices to debug the problem yourself. Run this code:
lastwarn('')
for m = 1:currentsize(1)
for n = 1:currentsize(2)
replacement{m,n} = strrep(current{m,n}, '"', '');
if ~isempty(lastwarn)
keyboard
lastwarn('')
end
end
end
This will launch the debugger when a warning is raised, allowing you to check the content of current{m,n}
It is mentionned in the documentation of strrep that :
The strrep function does not find empty strings for replacement. That is, when origStr and oldSubstr both contain the empty string (''), strrep does not replace '' with the contents of newSubstr.
You can use this user function substr like this :
for m = 1:currentsize(1)
for n = 1:currentsize(2)
replacement{m,n} = substr(current{m,n}, 2, -1);
end
end
Please use xlswrite function like this :
[status,message] = xlswrite(___)
and check the status if it is zero, that means the function did not succeed and an error message is generated in message as string.

Matlab - Error using save Cannot create '_' because '_____' does not exist

I have some data in a cell array,
data2={[50,1;49,1;26,1];...
[36,2;12,2;37,2;24,2;47.3,2];}
and names in another cell array,
names2={'xxx/01-ab-07c-0fD3/0';'xxx/01-ab-07s-0fD3/6';}
I want to extract a subset of the data,
data2_subset=data2{1,:}(:,1);
then a temporary file name,
tempname2=char(names2(2));
an save the subset to a text file with
save (tempname2, 'data2_subset', '-ASCII');
But I get this error message: _
Error using save
Cannot create '6' because 'xxx/01-ab-07s-0fD3' does not exist.
To try to understand what is happening, I created a mock dataset with simpler names:
names={'12-05';'14-03'};
data={[50,1;29,1;25,1];[35,2;22,2;16,2;38,2];[40,3;32,3;10,3;44,3;43,3];};
data_subset=data{1,:}(:,1);
tempname=char(names(2));
save (tempname, 'data_subset', '-ASCII');
in which case the save command works properly.
Unfortunately I still do not understand what the problem is in the first case. Any suggestions as to what is happening, and of possible solutions?
MATLAB is interpreting the the forward slashes (/) as directory separators and 6 as the intended file name (your second example doesn't have this slash problem).
Since the relative directory tree xxx/01-ab-07s-0fD3/ doesn't exist, MATLAB can't create the file.
To solve the problem, you can either create the directories beforehand using mkdir():
>> pieces = strsplit(tempname2,'/');
>> mkdir(pieces{1:2});
>> save(tempname2, 'data2_subset', '-ASCII');
or replace the / with some other benign symbol like _:
>> tempname3= strrep(tempname2,'/','_');
>> save (tempname3, 'data2_subset', '-ASCII');
(which works for me).