# How can Ido the same operations with multiples files using for-loop

14 views (last 30 days)
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
%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
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')
For example, how can I do the first step, the plot? How can I plot the first file?
Thanks!
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:

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
. . .
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
. . .
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
Adam Danz on 3 Sep 2019

Jose Rego Terol on 2 Sep 2019
Thanks for your comment. Here I attached the functions as m-files and the files I want to load both to the for-loop and to the analysis function.
Now, when I run the wrapper I got this error:
>> Spike_analysis_wrapper2
Must be a string scalar or character vector.
Error in Spike_analysis2 (line 18)
Error in Spike_analysis_wrapper2 (line 35)
Spike_analysis2(k)
It's strange because yesterday it worked, but using the filepairs.
Thanks again!
Jose Rego Terol on 8 Sep 2019
What is the output of spike_analysis()? A matrix, vector, cell array?
Is the output always the same size?
The outputs are all a vector. The file is converted to cell (struct2cell), and the outputs are obtained from each file. If the output keeps the same format as the file, the output is a cell. But I do not think so, right? Output is merely a number.
I've seen when I run the loop that the value of spike_analysis_file1(baseFileName) is always the first output of this function. I do not understand why the program only takes the first one instead of all the outputs written in the script.