Changing a function to take an input of cells rather than a matrix

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

Please give an example of inputs as the function is now and the inputs you would like to pass.
I want to be able to input an array of cells in 1xN form and within each cell is a Nx2 matrix of times and intensities from an image.
right now I have to manually input all each different matrix I want to input a cell array

Sign in to comment.

Answers (2)

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

In this case I would need a for loop around everything to access each cell. Is that correct?
So I selected all the 'data()' and changed them to data{1,k}() where k is the index for my for loop around the algorithm that is: k = 1:length(data).
For some reason with this, the first iteration works just fine but the rest dont.
any ideas?
thanks
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.

Sign in to comment.

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

So I tried this as well and it wont accept my cell input or my double input anymore. I have what you have but with a for loop in a similar fashion to above. I can't seem to figure out why it won't accept my input. Maybe its just evening brain.
From my point of view:
  1. make sure that your friends QDViewer runs with some test data
  2. figure out the exact requirement on the input data of QDViewer
  3. 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.
  4. do not change QDViewer
  5. My_QDViewer may call QDViewer several times in a loop

Sign in to comment.

Asked:

on 13 Aug 2012

Community Treasure Hunt

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

Start Hunting!