MATLAB - create a list for multiple files - matlab

I dont know if the title is appropriate, but i need to import several files e.g. 25 (files like info.asd , ina.asd, sdd.asd etc). So in my opinion its possible to import them via a for loop instead of hardcoding the operation. Any ideas how to implement the list in matlab, so the software 'd know what to import?

You can do it without loop with this function. sPath is the path containing your files and sExt is the extension of the files you want to list.
function cList = fileList(sPath, sExt)
if nargin == 1
sExt = '.asd';
end
% List files in the given path
stDir = dir(sPath);
tDir = struct2table(stDir);
tFile = tDir(~tDir.isdir, :);
% Keep only file with the right extension
cList = tFile.name;
[~, cList, cExt] = cellfun(#fileparts , ...
cList , ...
'UniformOutput', false);
vIsIni = cellfun(#(x) strcmpi(x, sExt), cExt);
cList = cList(vIsIni);
end

Related

Finding pair of files in a folder

I have a folder with tens of thousand of files. Every file in the folder should have a pair matching except the initial few letter, for example:
X_Date_Time_Place.dat
Y_Date_Time_Place.dat
Each X_* and Y_* combine to make one pair of files.
However, there always be some thousand of files extra which need to be eliminated from the folder. The extra files are also of the same type but without pair. For example, there may be more 'X_Date_Time_Place.dat' then 'Y_Date_Time_Place.dat'. Only variables in the file names are 'Date', 'Time' and 'Place'.
I have written a simple script (using for loop) that takes the name of one file and check all the other files in a loop until it finds its match. However, it is taking enormous amount of time to find a pair.
Is there any faster and more efficient way to do it?
You can split to two lists:
xlist = dir( fullfile( path_to_folder, 'X_*.dat') );
ylist = dir( fullfile( path_to_folder, 'Y_*.dat') );
%// remove prefixes
xlist = cellfun(#(x) x(3:end), {xlist.name}, 'uni', false);
ylist = cellfun(#(y) y(3:end), {ylist.name}, 'uni', false);
common = intersect(xlist, ylist);
Using intersect to find the common suffixes leaves you with common holding all Date_Time_Place.dat for which you have BOTH X_Date_Time_Place.dat and Y_Date_Time_Place.dat.
To get all pairs:
allParis = cellfun(#(c) {fullfile(path_to_folder,['X_',c]),
fullfile(path_to_folder,['Y_',c])}, common, 'uni', false);
You can use the function dir and specify a string and/or an extension that you want your filename to contain :
In your example :
I=dir('* _Date_Time_Place *.dat')
Will return a struct I whose fields will be all the filenames containing the string *_Date_Time_Place* and having the extension .dat .
You can then access to the elements in the struct with calls to I(1), I(2).
Minor note :
For this to work, your current folder must be the one where your files are.
Well, I don't have 10,000 files formatted like this but here is what I would do.
Xfiles = dir('X*.dat');
filenames = {Xfiles.name};
% Here I would determine how many pairs I am looking for (the unique X's)
% I am assuming that your X files are unique.
% remove the "X" from the file name
filenames2 = cellfun(#(x) repexprep(x, 'X',''));
keys = filenames2;
values = 1:length(filenames2);
fileMap = containers.Map(keys, values);
% for each Y look for the filename
Yfiles = dir('Y*.dat');
Yfiles2 = cellfun(#(x) repexprep(x, 'Y',''));
pairs = cell(length(Yfiles2),2);
% this assumes that for every Y there must be an X
% if this is not true then handle the empty idx case.
for x = 1:length(Yfiles2)
idx = fileMap(Yfiles2{x});
pairs(x,:) = {Xfiles(idx), Yfiles(idx)};
end

Reconstruct directories from file MATLAB

Thanks for your help.
The problem is:
I need the user to select a file based on an extension lets say .tif. I used the standard method, i.e.
[flnm,locn]=uigetfile({'*.tif','Image files'}, 'Select an image');
ext = '.tif';
But I need to fetch other image files from other subdirectories. Say the directory name returned to locn is: /user/blade/checklist/exp1/trial_1/run_1/exp001.tif. Image goes to exp100.tif.
I want to access:
/user/blade/checklist/exp1/trial_1/run_2/exp001.tif.
Also access:
/user/blade/checklist/exp1/trial_2/run_2/exp001.tif.
Up to trial_n
But if I list directory in /user/blade/checklist/exp1/, I get all folders therein from where I can reconstruct the right path. The naming structure is orderly.
My current solution is
[flnm,locn]=uigetfile({'*.tif','Image files'}, 'Select an image');
ext = '.tif';
parts = strsplit(locn, '/');
f = fullfile(((parts{end-5}),(parts{end-4}),(parts{end-3}),(parts{end-2}),(parts{end-1}));
Which is really ugly and I also lose the first /. Any help is appreciated.
Thanks!
First, get the file location as you did; note a small change I've made to make use of the variable ext.
ext = '.txt';
[flnm,locn]=uigetfile({['*',ext]}, 'Select an image');
parts = strsplit(locn,'/');
root = parts(1:end-4);
parts has 2 information - 1) path of the selected file; 2) path of your working folder, checklist, which you need. So root has the working folder.
Then, list out all the files you wanted, and put them in a cell array.
The file names should contain partial (subfolder) paths; it's not difficult to follow the pattern.
flist = {'trial_1/run_1/exp001.tif', ...
'trial_1/run_1/exp002.tif', ...
'trial_1/run_2/exp001.tif', ...
'trial_2/run_1/exp001.tif', ...
'trial_2/run_2/exp001.tif'};
I just enumerated a few; you can use a for loop to automatically generate trial_n and expxxx.tif. An example code to generate the complete file list (but not "full paths") -
flist = cell(10*2*100,1);
for ii = 1:10
for jj = 1:2
for kk = 1:100
flist{sub2ind([10,2,100],ii,jj,kk)} = ...
sprintf('trial_%d/run_%d/exp%03d%s', ii,...
jj, kk, ext);
end
end
end
Finally, use strjoin to concatenate the first part (your working folder) and second part (needed files in subfolders). Use cellfun to call strjoin for each cell in the file list cell array, so for every file you want you get a full path.
full_flist = cellfun(#(x) strjoin([root, x],'/'), ...
flist, 'UniformOutput', false);
Example output -
>> locn
locn =
/home/user/Downloads/exp1/trial_1/run_1/
>> for ii = 1:5
full_flist{ii}
end
ans =
/home/user/Downloads/trial_1/run_1/exp001.tif
ans =
/home/user/Downloads/trial_1/run_1/exp002.tif
ans =
/home/user/Downloads/trial_1/run_2/exp001.tif
ans =
/home/user/Downloads/trial_2/run_1/exp001.tif
ans =
/home/user/Downloads/trial_2/run_2/exp001.tif
>>
Note: You can either use
strjoin(str1, str2, '/')
or
sprintf('%s/%s', str1, str2)
They are equivalent.

Save loop results

I have a simple question but I don't know how to solve it.
I want to process all the files in a folder and I want to write the output values on a separate line on a matrix. After direct the folder and get the list of the files and their names
filePattern=fullfile( myPath,'*.txt')
I applied a 'loop'. To save the results on each line for every file, this is what I'm doing but it doesn't work (the code works with one file, not with all of them).
text= {baseFileName, result2b, result3b, result4b, result5b};
Is there something wrong?
Thanks in advance! Greetings,
Emma
PD)
myPath = 'C:\SP\';
% if ~isdir(myPath)
% errorMessage = sprintf('Error: The following folder does not exist:\n%s', myFolder);
% uiwait(warndlg(errorMessage));
% return;
a= dir (fullfile(myPath,'*.DIM')); %
fileNames = { a.name };
filePattern=fullfile( myPath,'*.txt');
txtFiles= dir(filePattern);
for k = 1:length(txtFiles)
baseFileName=txtFiles(k).name;
fullFileName= fullfile(myPath,baseFileName);
fid=fopen(fullFileName, 'r+');
for i = 1:18
m{i} = fgetl(fid);
end
result2 = m{18};
result2b= result2([12:19]);
(...)
EDIT:
I added a screenshoot about my variables. Is it possible because of the txtFiles is wrong?

Load Multiple .mat Files to Matlab workspace

I'm trying to load several .mat files to the workspace. However, they seem to overwrite each other. Instead, I want them to append. I am aware that I can do something like:
S=load(file1)
R=load(file2)
etc.
and then append the variables manually.
But there's a ton of variables, and making an append statement for each one is extremely undesirable (though possible as a last resort). Is there some way for me to load .mat files to the workspace (by using the load() command without assignment) and have them append?
Its not entirely clear what you mean by "append" but here's a way to get the data loaded into a format that should be easy to deal with:
file_list = {'file1';'file2';...};
for file = file_list'
loaded.(char(file)) = load(file);
end
This makes use of dynamic field references to load the contents of each file in the list into its own field of the loaded structure. You can iterate over the fields and manipulate the data however you'd like from here.
It sounds like you have a situation in which each file contains a matrix variable A and you want to load into memory the concatenation of all these matrices along some dimension. I had a similar need, and wrote the following function to handle it.
function var = loadCat( dim, files, varname )
%LOADCAT Concatenate variables of same name appearing in multiple MAT files
%
% where dim is dimension to concatenate along,
% files is a cell array of file names, and
% varname is a string containing the name of the desired variable
if( isempty( files ) )
var = [];
return;
end
var = load( files{1}, varname );
var = var.(varname);
for f = 2:numel(files),
newvar = load( files{f}, varname );
if( isfield( newvar, varname ) )
var = cat( dim, var, newvar.(varname) );
else
warning( 'loadCat:missingvar', [ 'File ' files{f} ' does not contain variable ' varname ] );
end
end
end
Clark's answer and function actually solved my situation perfectly... I just added the following bit of code to make it a little less tedious. Just add this to the beginning and get rid of the "files" argument:
[files,pathname] = uigetfile('*.mat', 'Select MAT files (use CTRL/COMM or SHIFT)', ...
'MultiSelect', 'on');
Alternatively, it could be even more efficient to just start with this bit:
[pathname] = uigetdir('C:\');
files = dir( fullfile(pathname,'*.mat') ); %# list all *.mat files
files = {files.name}'; %# file names
data = cell(numel(files),1); %# store file contents
for i=1:numel(files)
fname = fullfile(pathname,files{i}); %# full path to file
data{i} = load(fname); %# load file
end
(modified from process a list of files with a specific extension name in matlab).
Thanks,
Jason

matlab code source

how to write a program in matlab that reads a certain number of images let's say 20 for example which are saved in a given directory (C:) such that later i can use them. suppose that the images are saved by numbers. later, i am gonna use them.
I'd have the code look something like this. Assuming cell array im holds your images.
Write out:
IMG_DIR = 'C:\';
filename_root = 'image';
IMG_EXT = '.jpg';
NUM_IMAGES = 20;
for i = 1:NUM_IMAGES
imwrite(im{i}, [IMG_DIR filename_root num2str(i) IMG_EXT]);
end
Read in:
for i = 1:NUM_IMAGES
im{i} = imread([IMG_DIR filename_root num2str(i) IMG_EXT]);
end
If you don't know how many there are, you can also use ls command (works differently in Windows vs. Linux).
If you don't know, in advance, which files will be in there, but you know that they have the string in them, 'rawImage' (like 'rawImage001.jpg' etc.) you can do something like
a = dir('c:\temp');
requiredBaseFileName = 'rawImage'; % you want them to contain the substring 'rawImage'
for i = 1:length(a),
fileName = a(i).name;
if(isempty(strfind(fileName,'.jpg')) & isempty(strfind(fileName,'.png')))
continue;
end
if(isempty(strfind(fileName,requiredBaseFileName)))
continue;
end
% do your processing here
end