123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- function [globalPar, cPars] = ...
- fitCentersPixel(path, patientID, cax, cm, centers,sigma2)
- %path is the core directory
- %cax are the mid intervals in images
- %cm are the interval durations (1,n)
- %data are the images
- %nclass is number of typical responses sought
- npar=1;
- nglob=2;
- nclass=size(centers,1);
-
- cm2=ones(nclass,1)*cm';
-
- %w=sqrt(cm2.*centers)./sum(cm2.*centers,2);
- w=ones(nclass,1)*sqrt(cm)';
- %make sure that the function that is most similar to input function has
- %a high weight on maximum value, which comes as the second reading
- %abandonded, because decay time gets shortened and fitting of the slow
- %rise is given up in favor of meeting the high point through k1 value
- %[~,im]=max(centers(:,2));
- %w(im,2)=w(im,2)+0.1*(sqrt(max(cm))-w(im,2));
-
-
- %cax are the delays
- %c
- valueGeneratorSettings.type='poisson';
- valueGeneratorSettings.parameters=[25];
- valueGeneratorSettings.u=[0,Inf];
-
- ivar=2;
- valueGeneratorSettings(ivar).type='loggaus';
- valueGeneratorSettings(ivar).parameters=[1.5,1];%log10(mean),log10(std)
- valueGeneratorSettings(ivar).u=[0,Inf];
- ivar=ivar+1;
-
- valueGeneratorSettings(ivar).type='loggaus';
- valueGeneratorSettings(ivar).parameters=[-1,1];%log10(mean),log10(std)
- valueGeneratorSettings(ivar).u=[0,Inf];
- ivar=ivar+1;
- valueGeneratorSettings(ivar).type='gaus';
- valueGeneratorSettings(ivar).parameters=[10,2];%log10(mean),log10(std)
- valueGeneratorSettings(ivar).u=[-Inf,Inf];
- ivar=ivar+1;
- %for individual fits
- valueGeneratorSettings1.type='loggaus';
- valueGeneratorSettings1.parameters=[-3,1];
- valueGeneratorSettings1.u=[0,Inf];
- ivar=2;
-
- valueGeneratorSettings1(ivar).type='flat';
- valueGeneratorSettings1(ivar).parameters=[0,1];
- valueGeneratorSettings1(ivar).u=[0,1];
- ivar=ivar+1;
-
- valueGeneratorSettings1(ivar).type='loggaus';
- valueGeneratorSettings1(ivar).parameters=[-7,2];
- valueGeneratorSettings1(ivar).u=[0,Inf];
- ivar=ivar+1;
-
- valueGeneratorSettings1(ivar).type='gaus';
- valueGeneratorSettings1(ivar).parameters=[10,5];
- valueGeneratorSettings1(ivar).u=[0,Inf];
-
-
- options = optimoptions(@lsqnonlin);
- options.Display='off';
- %[options.OptimalityTolerance,options.FunctionTolerance,options.StepTolerance];
- %holds best estimate
- fmin=1e30;
- n=20;
- n1=20;
- imin=-1;
- nFitIndividual=4;
- qfit=zeros(1,nFitIndividual*nclass);
- qfitmin=qfit;
- [x,ul,ub]=generateInitialValues(valueGeneratorSettings);
- for i=1:n
-
- %first estimate input functions
- %take function with maximum response as IVF surrogate
- %assume first row (ventricle) is the input function
- cay=centers(1,:)';
- w=ones(size(cay));
-
- fun=@(x)evaluateSingleDiffZero(cax,cay,w,x);
- [x0,ul,ub]=generateInitialValues(valueGeneratorSettings);
-
- [x1,resnorm,residual,exitflag,output,lambda,jacobian] = lsqnonlin(fun,x0,ul,ub,options);
- fprintf('A %f\n',x1(1));
-
- while x1(1)<1
- [x0,ul,ub]=generateInitialValues(valueGeneratorSettings);
- [x1,resnorm,residual,exitflag,output,lambda,jacobian] = lsqnonlin(fun,x0,ul,ub,options);
- fprintf('A %f\n',x1(1));
- end
- %this gets A, tau and alpha
- %A shouldn't be trivial
-
- fprintf('[%d] Global fit: (%f,%f,%f %f) (%f,%f,%f %f)\n',i,x0(1),x0(2),x0(3),x0(4),...
- x1(1),x1(2),x1(3),x1(4));
-
- chiSum=0;
- %now fit every curve individually with the known input function
- for j=1:nclass
- [m mi]=max(centers);
- [fm mj]=max(m);
- cay=centers(mi(mj),:)';
- w=ones(size(cay));
- cay=centers(j,:)';
- w=ones(size(cay));
- w=sqrt(cm);
-
- fun1=@(par)evaluateSingleDiff(cax,cay,w,x1,par);
-
- qpar=zeros(1,4);
- qmin=1e30;
- for k=1:n1
- [par0,ul1,ub1]=generateInitialValues(valueGeneratorSettings1);
- [par1,resnorm,residual,exitflag,output,lambda,jacobian] = ...
- lsqnonlin(fun1,par0,ul1,ub1,options);
- fchi2=sqrt(residual'*residual);
- if fchi2<qmin
- qmin=fchi2;
- qpar=par1;
- end
- end
- qfit((j-1)*nFitIndividual+1:j*nFitIndividual)=qpar;
- fprintf('Center: %d (%f %f %f %f)/(%f %f %f %f)\n',j,...
- par0(1),par0(2),par0(3),par0(4),...
- par1(1),par1(2),par1(3),par1(4));
- %residual
- chiSum=chiSum+qmin;
- end
- %writematrix(ci,fullfile(path,sprintf('CI%d.txt',i)),'Delimiter','tab');
- %output
- chi2=chiSum;
-
- if chi2<fmin
- fmin=chi2;
- x=x1;
- imin=i;
- qfitmin=qfit;
- %fci=ci;
- end
- fprintf('chi2: %d,%d\n',size(chi2,1),size(chi2,2));
- %writematrix([chi2 x1],fullfile(path,sprintf('fitPar%d.txt',i)),'Delimiter','tab');
- fprintf('Done %d %f (%.2f,%.2f,%.2f)/(%.2f,%.2f,%.2f)\n',...
- i,chi2,x0(1),x0(2),x0(3),x1(1),x1(2),x1(3));
- [x0,ul,ub]=generateInitialValues(valueGeneratorSettings);
-
-
- end
-
- %this is the result that will be used by k1 calculator
- sigmaCode=sprintf('%.2f',sigma2);
- sigmaCode=strrep(sigmaCode,'.','p');
- code=sprintf('%s_%d_%s_Pixel',patientID,nclass,sigmaCode);
- ofile=fullfile(path,patientID,sprintf('%s_fitParFinal.txt',code));
- writematrix([fmin x qfitmin],ofile,'Delimiter','tab');
- %ofile=fullfile(path,sprintf('CIFinal_%d_%d.txt',nclass,realizationId));
- %writematrix(fci,ofile,'Delimiter','tab');
- disp(sprintf('Found min at %d',imin));
-
- globalPar=[x(1:3) 0 0 0];
-
- cPars=reshape(qfitmin,[],nclass)';
- %reset k1 for those where BVF is nearly one
- %cPars(cPars(:,2)>0.4,1)=0;
- %reset k1 for those where k2 is abnormally large
- %cPars(cPars(:,3)>1,1)=0;
- opath=fullfile(path,patientID);
- plotFunctions(opath,code,globalPar,cPars,cax,centers);
-
-
- end
|