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

12 views (last 30 days)
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')
For example, how can I do the first step, the plot? How can I plot the first file?
Thanks!
  1 Comment
Stephen23
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.

Sign in to comment.

Accepted Answer

Adam Danz
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
Jose Rego Terol
Jose Rego Terol on 3 Sep 2019
Hi Adam,
The problem was this guy Spike_analysis2(fullFileName)
Thanks a lot for you patience and your time spent!

Sign in to comment.

More Answers (1)

Jose Rego Terol
Jose Rego Terol on 2 Sep 2019
Hi Adam,
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
Now reading footsignal_spike1.mat
Error using load
Must be a string scalar or character vector.
Error in Spike_analysis2 (line 18)
S = load(file1);
Error in Spike_analysis_wrapper2 (line 35)
Spike_analysis2(k)
It's strange because yesterday it worked, but using the filepairs.
Thanks again!
  5 Comments
Adam Danz
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?
Jose Rego Terol
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.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!