How can I apply a function to each file in each folder of my directory?

조회 수: 17 (최근 30일)
JJH
JJH 2018년 11월 15일
편집: Nick 2018년 11월 15일
I have some code that takes data from a set of folders and sorts it using datenum.
Index = 1:13;
SpectrumFileInfo = dir('Spectrum Data*');
SpectrumFileInfo=SpectrumFileInfo(Index);
NSpec = length(SpectrumFileInfo);
for i = 1:NSpec
SFI(i) = SpectrumFileInfo(i);
end
h=figure;
[SpectrumParams,FittedWavelengths,InternalTemp]=deal(cell(NSpec,1));
for k = 1:NSpec
FolderName = SpectrumFileInfo(k).name;
Direc = dir([FolderName '\I*.csv']);
[~,idx]=sort([Direc.datenum]);
Direc=Direc(idx);
DataPointsSpec=length(Direc)-2;
array=zeros(DataPointsSpec,4);
end
I now want to apply a function to every file in every folder. I tried something like this
for k = 1:NSpec
FolderName = SpectrumFileInfo(k).name;
Direc = dir([FolderName '\I*.csv']);
[~,idx]=sort([Direc.datenum]);
Direc=Direc(idx);
DataPointsSpec=length(Direc)-2;
array=zeros(DataPointsSpec,4);
for kk = 2:DataPointsSpec+1;
specdata = SpectrumPeakFitCSV(filename);
end
end
where the function I am using is
function [params,Wavelength,Intensity,wavpeak]=SpectrumPeakFitCSV(filename)
SpectrumData=csvread(filename)
Wavelength=SpectrumData(:,1);
Intensity=SpectrumData(:,2);
%select region from 835 to 865
p1=1;
p2=501;
Wavelength=Wavelength(p1:p2,1);
Intensity=Intensity(p1:p2,1);
Max=max(Intensity);
peak=find(Intensity==Max(1));
wavpeak=Wavelength(peak(1));
fun=@(x,Wav)Lorentzian(x(1),x(2),x(3),Wav)+x(4);
dark=Intensity(1);
opts = optimset('Display','off');
x=lsqcurvefit(fun,[Max(1),1,wavpeak,dark],Wavelength,Intensity,[0.5*Max(1) 0 wavpeak-0.2 0.9*dark],[2*Max(1) 3 wavpeak+0.2 1.5*dark],opts);
params=x ;%scale, width, centre, dark
end
but there is a problem with me using filename here. How do I refer to each of the files? I have included four files below. The first two would normally be in one folder called Spectrum Data 1 and the second two in Spectrum Data 2 (there will actually be about 50 files and 12 folders).

답변 (1개)

Nick
Nick 2018년 11월 15일
편집: Nick 2018년 11월 15일
You pretty much already have everything you need to get the filename in your code here, An additional problem you will run into later in your code is the fact you only assigned one output variable while the function outputs 4 and no indexing so it keeps overwritting it. You would end up with an error due to wrong number of outputs and when you fix that but don't index you will only have the last value. Here are 2 solutions on how to approach the problem as i am not sure you want to sort and evaluate per folder (like you did now) or for all files in all folders.
allData = cell(1, NSpec)
for folderIdx = 1:NSpec
% get full file path of the folder, so you do not have to be in the directory for it to work
folderName = fullfile(SpectrumFileInfo(folderIdx).folder,SpectrumFileInfo(folderIdx).name);
fileNames = dir([folderName '\I*.csv']);
[~,idx]=sort([fileNames.datenum]);
fileNames=fileNames(idx);
% you only need to check the number of elements in fileNames to know the number of csv files when u use that filter
dataArray = zeros(numel(fileNames),4);
for fileIdx = 1:numel(fileNames)
% get the file name again full file path
filename = fullfile(fileNames(fileIdx).folder, fileNames(fileIdx).name);
% the way your output is defined in your function at the moment you would need to
% assign 4 output variables, you can however just output a struct or a 1x4 vector
% in the SpectrumPeakFitCSV function and that would make this a bit less verbose
[dataArray(fileIdx,1),dataArray(fileIdx,2),...
dataArray(fileIdx,3),dataArray(fileIdx,4)] = SpectrumPeakFitCSV(filename);
end
allData{folderIdx} = dataArray;
end
This will sort the spectra by date per folder as i am assuming that was what your goal is. If you want all spectra by date you need to take an additional step, If speed is not very important a quick fix to do that would be:
allFiles = struct.empty;
for folderIdx = 1:NSpec
folderName = fullfile(SpectrumFileInfo(folderIdx).folder,SpectrumFileInfo(folderIdx).name);
currentFiles = dir([folderName, '\I*.csv']);
allFiles(end+1, end+numel(fileNames)) = currentFiles;
end
% filter based
[~,idx]=sort([allFiles.datenum]);
fileNames=allFiles(idx);
dataArray = zeros(numel(fileNames),4);
for fileIdx = 1:numel(fileNames)
filename = fullfile(fileNames(fileIdx).folder, fileNames(fileIdx).name);
[dataArray(fileIdx,1),dataArray(fileIdx,2),...
dataArray(fileIdx,3),dataArray(fileIdx,4)] = SpectrumPeakFitCSV(filename);
end
I also assumed every output from that function is a scalar. So if some of them are vectors or arrays you might need to adjust the indexing and preallocate a larger array, use a cell array or struct

카테고리

Help CenterFile Exchange에서 Environment and Settings에 대해 자세히 알아보기

태그

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by