Changing a function to take an input of cells rather than a matrix
7 views (last 30 days)
Show older comments
So I have a Matlab function created by friend of mine and I need to change it such that it will work properly with an input of cells rather than just a single matrix.
the code is :
%%QDViewer v1.5 September 18 2009
function [] = QDViewer(data,threshold)
close all %closes figures
disp(' ');
disp('Running QDViewer.m');
disp('To terminate the program (a la ctrl-alt-del) hit CTRL+C.');
tic;
%Overload program to accept no input for threshold
if nargin == 1
disp('Threshold set to default (35%).');
threshold = 35;
else
if threshold>100 || threshold<0
error('The value for threshold is supposed to be a percentage of the highest peak, a value between 0 and 100. Please run the program again with an appropriate parameter.');
else
disp(['Threshold set to ' int2str(threshold) '%.']);
end
end
%This new version of the qd program knows how to take the metadata away
%from the formatted matlab files.
dotwavelength=data(1,2);
pixelx = data(2,2);
pixely = data(3,2);
% date = data(4,2);
% datestr = int2str(date);
% datestr = [datestr(1:4) '-' datestr(5:6) '-' datestr(7:8)];
runname = ['blinky' int2str(data(5,2))];
numcycle = data(6,2);
time = data(7,2); %in seconds
numwavelengths = data(8,2);
wavelengths = data(9:(9+numwavelengths-1),2)';
pointdata = ['[' int2str(dotwavelength) 'nm, ' '05222012' ': ' runname ' (' int2str(pixelx) ',' int2str(pixely) ')]'] %#ok<NOPRT> %This string will be used in plots later.
%Now remove that data so that we have an array that looks like the old
%version:
data = data((9+numwavelengths):end,:);
result = zeros(numcycle,3);
maxintensity = max(data);
maxintensity = maxintensity(2); %global max intensity
threshold = maxintensity*threshold/100;
time=(time/60)/numcycle; %time in minutes per cycle
Z=zeros(numcycle,numwavelengths); %Variable used in the 3D plot
% Initialize
count = 0;
intensity=zeros(1,numcycle);
for i = 1:numcycle
submatrix = data((i-1)*numwavelengths+1:i*numwavelengths,2);
if (max(submatrix))>threshold
count=count+1;
result(count,2) = max(submatrix); %max intensity for field
intensity(i) = max(submatrix);
index=mod(find(submatrix==result(count,2)),numwavelengths);
if index==0
index=numwavelengths;
end
result(count,3) = wavelengths(index(1));%wavelength
result(count,1) = i*time + index(1)*time/numwavelengths;
%time per cycle + time between wavelengths
end
for j=1:numwavelengths
if submatrix(j)>threshold;
Z(i,j)=submatrix(j)/maxintensity*100;
else
Z(i,j)=0;
end
end
end
%Normalized Intensity
normintensity = zeros(size(intensity));%Loop normalizes telegraph to be 0 / 1
for i=1:length(intensity)
if intensity(i)~=0
normintensity(i) = 1;
else
normintensity(i) = 0;
end
end
%On / Off time probabilities
%Initialize to zero
jon = 0;
kon = 0;
joff = 0;
koff = 0;
oncount = zeros(1,length(normintensity)); %On-times, in cycles (not seconds)
offcount = zeros(1,length(normintensity));
for i=1:length(normintensity)
if normintensity(i)==1
jon = jon+1;
koff = koff+1;
offcount(koff)=joff;
joff=0;
elseif normintensity(i)==0
joff = joff+1;
kon = kon+1;
oncount(kon)=jon;
jon=0;
end
end
oncount(oncount==0)=[]; %remove all zeros.
offcount(offcount==0)=[];
onfreq = zeros(1,length(oncount)); %Frequency of a blink being on this long
offfreq= zeros(1,length(offcount));
for i = 1:max(length(oncount),length(offcount))
onfreq(i)= sum(oncount==i);
offfreq(i)= sum(offcount==i);
end
onfreq = onfreq/sum(onfreq); %Normalize to percentages.
offfreq = offfreq/sum(offfreq);
%MLE Algorithm (fitting to Probs):
S_on_MLE = 1/length(oncount)*sum(log(oncount));
crit_on = (1+1/S_on_MLE) %#ok<NOPRT>
S_off_MLE = 1/length(offcount)*sum(log(offcount));
crit_off = (1+1/S_off_MLE) %#ok<NOPRT>
t_min = 1;
t_max = numcycle;
tonlast = (find(onfreq~=0, 1, 'last'));
if(isempty(tonlast))
tonlast = numcycle;
end
t_on = linspace(1,tonlast); %set up our timedomain, starting from lowest resolution to highest occupied on-time.
A_on = (crit_on-1)/(t_min^(1-crit_on)-t_max^(1-crit_on)); %normalizing constant
P_on = A_on*t_on.^(-crit_on);
tofflast = (find(offfreq~=0, 1, 'last'));
if(isempty(tofflast))
tofflast = numcycle;
end
t_off = linspace(1,tofflast);
A_off = (crit_off-1)/(t_min^(1-crit_off)-t_max^(1-crit_off));
P_off = A_off*t_off.^(-crit_off);
%%Marcel's Stuff
offtimes((1:length(offfreq)),1) = (1:length(offfreq))*time;
offtimes((1:length(offfreq)),2) = offfreq;
ontimes((1:length(onfreq)),1) = (1:length(onfreq))*time;
ontimes((1:length(onfreq)),2) = onfreq;
[row col] = find(offtimes == 0);
offtimes(row,:) = [];
[row col] = find(ontimes == 0);
ontimes(row,:) = [];
xlswrite('offtime.xls',offtimes);
xlswrite('ontime.xls',ontimes);
F = @(a,x)(a(2)*x.^(-a(1)));
param = [6 1];
[fit_off] = nlinfit(offtimes(:,1),offtimes(:,2),F,param);
F = @(a,x)(a(2)*x.^(-a(1)));
param = [6 1];
[fit_on] = nlinfit(ontimes(:,1),ontimes(:,2),F,param);
display(fit_off);
display(fit_on);
%%Plot results
result=result(1:count,1:3);
result(:,2)=result(:,2)/maxintensity*100;
intensity = intensity/maxintensity*100;
threshold = threshold/maxintensity*100;
regression=[ones(count,1) result(:,1)]\result(:,3); %#ok<NOPRT>
trendline(1:numcycle) = regression(1)+regression(2)*time*(1:numcycle);
% %Blinking telegraph
figure(1)
hold on;
title(['Intensity vs. Time ' pointdata], 'FontSize',16);
plot(time*(1:numcycle),intensity,'-black');
plot(time*(1:numcycle),threshold,'-r'); %show threshold line
xlabel('Time (min)','FontSize',14);
ylabel('Intensity (normalized a.u.)','FontSize',14);
axis([0 time*numcycle 0 105]);
hold off;
end
What I really need to know is how to properly edit the recursive stuff so that my the stuff I'm displaying (fit_off, fit_on, crit_on and crit_off) end up as nice outputs.
Sorry if this isn't so clear. Its hard to explain particularly because I didn't write the code myself and I'm not a pro at Matlab yet.
Thanks,
Marcel
2 Comments
Matt Fig
on 13 Aug 2012
Please give an example of inputs as the function is now and the inputs you would like to pass.
Answers (2)
Babak
on 13 Aug 2012
All you need to do is to change all the occurances of data(.,.) in your function to data{.,.}. This way wherever you are accessing the elemnts of the matrix with (.,.) you access the coresponding element of the cell with {.,.} instead.
As for where you're saying:
wavelengths = data(9:(9+numwavelengths-1),2)';
you need to keep it same as it is, but again wavelengths will still be a cell and later you need to change all the occurances of wavelengths(.,.) to wavelengths{.,.}
YOu got to do same for the line
submatrix = data((i-1)*numwavelengths+1:i*numwavelengths,2);
3 Comments
Babak
on 14 Aug 2012
You don't need for loop! data{.,.} accesses a component of data object which is a cell similar to data(.,.) which accesses an element of a matrix. by replacing I mean do the following for example, replace:
dotwavelength=data(1,2); pixelx = data(2,2); pixely = data(3,2);
with
dotwavelength=data{1,2}; pixelx = data{2,2}; pixely = data{3,2};
After you do all these replacements, data is considered a cell and you can no longer use this function for input of data as a matrix! the data that is the input to the function has to be a cell object.
per isakson
on 13 Aug 2012
Edited: per isakson
on 15 Aug 2012
Do you really need to change your friends function?
function My_QDViewer( my_cell_array, threshold)
data = ...
QDViewer( data, threshold );
end
.
or better something like
function My_QDViewer( my_input, threshold)
if isa( my_input, 'double' )
data = my_input;
elseif isa( my_input, 'cell' )
% convert to double array
data = ...
else
error( 'My_QDViewer:...', 'Illegal input: ... ),
end
QDViewer( data, threshold );
end
2 Comments
per isakson
on 14 Aug 2012
Edited: per isakson
on 15 Aug 2012
From my point of view:
- make sure that your friends QDViewer runs with some test data
- figure out the exact requirement on the input data of QDViewer
- write your own program, My_QDViewer, which is a wrapper around QDViewer. The purpose of My_QDViewer is to convert your cell array input data to the double array form required by QDViewer.
- do not change QDViewer
- My_QDViewer may call QDViewer several times in a loop
See Also
Categories
Find more on Matrix Indexing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!