How can Ido the same operations with multiples files using for-loop
12 views (last 30 days)
Show older comments
Jose Rego Terol
on 25 Aug 2019
Commented: Jose Rego Terol
on 8 Sep 2019
I developed the a code for one specific file (spike1.mat). Now I want to run this code for n files (spike1.mat, spike2.mat, spike3.mat, so on). Nested for-loop seems to be the best function, but I don't know how the (nested) for-loop makes the operation for the first file, for the second file, and so on. In other words,I don't know how I can integrate my operations into the for-loop because I don't know how to name the files.
This is my entire code:
clear;clc;
function = spike_analysis
load 'spike1.mat';
%Plot the spike with a corrected baseline
A=spike1(:,1);
B=spike1(:,2);
B1=B-(min(B)); %Baseline is 0 if the minimum value is different than 0.
figure(1)
plot(A,B1)
ylabel('Intensity (pA)')
xlabel('Time(s)')
title('1st spike')
format longG
% The parameters for the entire spike
% Charge of the entire spike
%The inmediate integration of the vector Intensity during the time is the
%charge (Q), i.e. the amount of molecules released per vesicle.
Q_spike=trapz(A,B1)*10^3
% The Increment of time of the Half Width of the spike
%Find the Time (second) when Intensity is maximum
%[a b]=max(Fst_spike(:,2));
%Time_maxI=Fst_spike(b,1)
% The Increment of time of Half Width.
%Find the half max value.
halfMax = max(B1) / 2;
index1_HW = find(B1 >= halfMax, 1, 'first'); %Gives the number of the row where data first drops below half the max.
index2_HW = find(B1 >= halfMax, 1, 'last'); %Gives the number of the row where data last rises above half the max.
Ti_HW=A(index1_HW,1)
Tf_HW=A(index2_HW,1)
AT_HW=(Tf_HW-Ti_HW)*10^6
%The Rise Time (the time span between the 50% and the 90% of the
%maxIntensty).
% Find the 90% of the maxIntensity.
RT_90 = max(B1) * 0.90;
index1_RT = find(B1 >= halfMax, 1, 'first'); %Gives the number of the row where data first rises above half the max.
index2_RT = find(B1 >= RT_90, 1, 'first'); %Gives the number of the row where data first drops below 90% of the max.
Ti_RT=A(index1_RT,1)
Tf_RT=A(index2_RT,1)
AT_RT=(Tf_RT-Ti_RT)*10^6
% The paramenters of the foot signal
load 'footsignal_spike1.mat'
A_f=footsignal_spike1(:,1);
B_f=footsignal_spike1(:,2);
figure (2)
plot(A_f,B_f)
ylabel('Intensity (pA)')
xlabel('Time(s)')
title('1st foot signal')
% Charge of the foot signal
Q_footsignal=trapz(A_f,B_f)*10^3
% Max amplitude of the foot signal
MaxI_f=max(B_f)
% Foot signal duration
Ti_f=min(A_f)
Tf_f=max(A_f)
AT_f=(Tf_f-Ti_f)*10^6
%Save the parameters and the entire spike figure
Table_parameters_spike1=table(MaxI_f,Q_footsignal,Ti_f,Tf_f,AT_f,AT_HW,AT_RT,halfMax,index1_HW,index2_HW,index1_RT,index2_RT,Q_spike,RT_90)
writetable (Table_parameters_spike1,'Parameters 1 spike.xlsx')
savefig(figure(1),'1st spike.fig')
savefig(figure(2),'1st footsignal.fig')
I tried this code https://matlab.fandom.com/wiki/FAQ#How_can_I_create_variables_A1.2C_A2.2C....2CA10_in_a_loop.3F but I cannot make it to work.
For example, how can I do the first step, the plot? How can I plot the first file?
Thanks!
1 Comment
Stephen23
on 26 Aug 2019
"I tried this code ...How_can_I_create_variables_A1.2C_A2.2C....2CA10_in_a_loop.3F but I cannot make it to work."
Creating variables (which is a singularly bad way to write code) is completely unrelated to processing multiple files in a loop. So that link does not help you at all.
You should start learning about how to process multiple files by reading this:
and following Adam Danz's advice.
Accepted Answer
Adam Danz
on 25 Aug 2019
Edited: Adam Danz
on 26 Aug 2019
A function is designed to have inputs and outputs though neither are required but in general the idea is:
---> [ do stuff] -->
For example, instead of defining what file should be loaded within the function, you could pass the file name in as an input like this.
function = spike_analysis(file1, file2) %make better variable names
load(file1) % though, see bullet points below
load(file2)
. . .
end
Now you can merely call your function like this
spike_analysis('spike1.mat', 'footsignal_spike1.mat')
If you'd like to loop through many files, you could write a wrapper function that merely selects the files and calls your main spike_analysis() function.
function = spike_analysis_wrapper()
filepairs = {
'spike1.mat', 'footsignal_spike1.mat';
'spike2.mat', 'footsignal_spike2.mat';
'spike3.mat', 'footsignal_spike3.mat';
'spike4.mat', 'footsignal_spike4.mat'};
% Loop through each row of filepairs
for i = 1:size(filepairs,1))
spike_analysis(filepairs{i,1},filepairs{i,2});
end
Here is a list of other advice pertaining to the code in your question
- Starting a function with "clear;clc;" is unnecessary. A function has its own workspace which starts out cleared.
- A general rule is that a function should do 1 thing. Often times it's cleaner to separate the analysis from the plotting (but not always).
- The function name should be descriptive; action verbs are good. plot_spike_analysis()
- Using load() without outputs and without specifying variables in the inputs is sloppy and is the least controlled way to load variables.
- Full paths are always better than mere filenames. If you have more than 1 file named "spike1.mat" anywhere on your matlab path, you have less control over which one is being loaded.
- Does the save commands at the end of your function overwrite the same file each time? Filenames should always be related to the unique inputs or contain a datetime stamp unless you intend for files to be overwritten. Alternatively, use full paths and save the files in different locations.
- Instead of writing the table and saving the figures within the plotting function, that could be done from the wrapper function as well (demo below) by using function outputs.
function = [Table_parameters_spike1, fig1, fig2] = spike_analysis(file1, file2) %make better variable names
load(file1) % though, see bullet points below
load(file2)
. . .
end
function = spike_analysis_wrapper()
filepairs = {
'spike1.mat', 'footsignal_spike1.mat';
'spike2.mat', 'footsignal_spike2.mat';
'spike3.mat', 'footsignal_spike3.mat';
'spike4.mat', 'footsignal_spike4.mat'};
% Loop through each row of filepairs
for i = 1:size(filepairs,1))
[Table_parameters_spike1, fig1, fig2] = spike_analysis(filepairs{i,1},filepairs{i,2});
writetable (Table_parameters_spike1,'Parameters 1 spike.xlsx')
savefig(fig1,'1st spike.fig')
savefig(fig2,'1st footsignal.fig')
end
16 Comments
More Answers (1)
Jose Rego Terol
on 2 Sep 2019
5 Comments
Adam Danz
on 8 Sep 2019
That's not the code I wrote. I think you're talking about this code here:
In that code I produce a table named "Parameters_spike1". You're not producing that table.
Look up the documentation for writetable. It expects the first input to be a table. In this line below, you are producing a table but you're not saving it.
table(t)
Your loop is not saving the data on each iteration. Instead, you're overwriting the table on each iteration. 't' is being overwitten each time the loop iterates.
for k = 1 : length(theFiles)
baseFileName = theFiles(k).name;
fullFileName = fullfile(myFolder, baseFileName);
fprintf(1, 'Now reading %s\n', baseFileName)
%Call the function Spike_analysis
t=spike_analysis_file1(baseFileName) %<---- PROBLEM HERE
end
What is the output of spike_analysis()? A matrix, vector, cell array?
Is the output always the same size?
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!