fitCentersPixel.asv 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. function [globalPar, cPars] = ...
  2. fitCentersPixel(path, patientID, cax, cm, centers,sigma2)
  3. %path is the core directory
  4. %cax are the mid intervals in images
  5. %cm are the interval durations (1,n)
  6. %data are the images
  7. %nclass is number of typical responses sought
  8. npar=1;
  9. nglob=2;
  10. nclass=size(centers,1);
  11. cm2=ones(nclass,1)*cm';
  12. %w=sqrt(cm2.*centers)./sum(cm2.*centers,2);
  13. w=ones(nclass,1)*sqrt(cm)';
  14. %make sure that the function that is most similar to input function has
  15. %a high weight on maximum value, which comes as the second reading
  16. %abandonded, because decay time gets shortened and fitting of the slow
  17. %rise is given up in favor of meeting the high point through k1 value
  18. %[~,im]=max(centers(:,2));
  19. %w(im,2)=w(im,2)+0.1*(sqrt(max(cm))-w(im,2));
  20. %cax are the delays
  21. %c
  22. valueGeneratorSettings.type='poisson';
  23. valueGeneratorSettings.parameters=[25];
  24. valueGeneratorSettings.u=[0,Inf];
  25. ivar=2;
  26. valueGeneratorSettings(ivar).type='loggaus';
  27. valueGeneratorSettings(ivar).parameters=[1.5,1];%log10(mean),log10(std)
  28. valueGeneratorSettings(ivar).u=[0,Inf];
  29. ivar=ivar+1;
  30. valueGeneratorSettings(ivar).type='loggaus';
  31. valueGeneratorSettings(ivar).parameters=[-1,1];%log10(mean),log10(std)
  32. valueGeneratorSettings(ivar).u=[0,Inf];
  33. ivar=ivar+1;
  34. valueGeneratorSettings(ivar).type='gaus';
  35. valueGeneratorSettings(ivar).parameters=[10,2];%log10(mean),log10(std)
  36. valueGeneratorSettings(ivar).u=[-Inf,Inf];
  37. ivar=ivar+1;
  38. %for individual fits
  39. valueGeneratorSettings1.type='loggaus';
  40. valueGeneratorSettings1.parameters=[-3,1];
  41. valueGeneratorSettings1.u=[0,Inf];
  42. ivar=2;
  43. valueGeneratorSettings1(ivar).type='flat';
  44. valueGeneratorSettings1(ivar).parameters=[0,1];
  45. valueGeneratorSettings1(ivar).u=[0,1];
  46. ivar=ivar+1;
  47. valueGeneratorSettings1(ivar).type='loggaus';
  48. valueGeneratorSettings1(ivar).parameters=[-7,2];
  49. valueGeneratorSettings1(ivar).u=[0,Inf];
  50. ivar=ivar+1;
  51. valueGeneratorSettings1(ivar).type='gaus';
  52. valueGeneratorSettings1(ivar).parameters=[10,5];
  53. valueGeneratorSettings1(ivar).u=[0,Inf];
  54. options = optimoptions(@lsqnonlin);
  55. options.Display='off';
  56. %[options.OptimalityTolerance,options.FunctionTolerance,options.StepTolerance];
  57. %holds best estimate
  58. fmin=1e30;
  59. n=20;
  60. n1=20;
  61. imin=-1;
  62. nFitIndividual=4;
  63. qfit=zeros(1,nFitIndividual*nclass);
  64. qfitmin=qfit;
  65. [x,ul,ub]=generateInitialValues(valueGeneratorSettings);
  66. for i=1:n
  67. %first estimate input functions
  68. %take function with maximum response as IVF surrogate
  69. %assume first row (ventricle) is the input function
  70. cay=centers(1,:)';
  71. w=ones(size(cay));
  72. fun=@(x)evaluateSingleDiffZero(cax,cay,w,x);
  73. [x0,ul,ub]=generateInitialValues(valueGeneratorSettings);
  74. [x1,resnorm,residual,exitflag,output,lambda,jacobian] = lsqnonlin(fun,x0,ul,ub,options);
  75. fprintf('A %f\n',x1(1));
  76. while x1(1)<1
  77. [x0,ul,ub]=generateInitialValues(valueGeneratorSettings);
  78. [x1,resnorm,residual,exitflag,output,lambda,jacobian] = lsqnonlin(fun,x0,ul,ub,options);
  79. fprintf('A %f\n',x1(1));
  80. end
  81. %this gets A, tau and alpha
  82. %A shouldn't be trivial
  83. fprintf('[%d] Global fit: (%f,%f,%f %f) (%f,%f,%f %f)\n',i,x0(1),x0(2),x0(3),x0(4),...
  84. x1(1),x1(2),x1(3),x1(4));
  85. chiSum=0;
  86. %now fit every curve individually with the known input function
  87. for j=1:nclass
  88. [m mi]=max(centers);
  89. [fm mj]=max(m);
  90. cay=centers(mi(mj),:)';
  91. w=ones(size(cay));
  92. cay=centers(j,:)';
  93. w=ones(size(cay));
  94. w=sqrt(cm);
  95. fun1=@(par)evaluateSingleDiff(cax,cay,w,x1,par);
  96. qpar=zeros(1,4);
  97. qmin=1e30;
  98. for k=1:n1
  99. [par0,ul1,ub1]=generateInitialValues(valueGeneratorSettings1);
  100. [par1,resnorm,residual,exitflag,output,lambda,jacobian] = ...
  101. lsqnonlin(fun1,par0,ul1,ub1,options);
  102. fchi2=sqrt(residual'*residual);
  103. if fchi2<qmin
  104. qmin=fchi2;
  105. qpar=par1;
  106. end
  107. end
  108. qfit((j-1)*nFitIndividual+1:j*nFitIndividual)=qpar;
  109. fprintf('Center: %d (%f %f %f %f)/(%f %f %f %f)\n',j,...
  110. par0(1),par0(2),par0(3),par0(4),...
  111. par1(1),par1(2),par1(3),par1(4));
  112. %residual
  113. chiSum=chiSum+qmin;
  114. end
  115. %writematrix(ci,fullfile(path,sprintf('CI%d.txt',i)),'Delimiter','tab');
  116. %output
  117. chi2=chiSum;
  118. if chi2<fmin
  119. fmin=chi2;
  120. x=x1;
  121. imin=i;
  122. qfitmin=qfit;
  123. %fci=ci;
  124. end
  125. fprintf('chi2: %d,%d\n',size(chi2,1),size(chi2,2));
  126. %writematrix([chi2 x1],fullfile(path,sprintf('fitPar%d.txt',i)),'Delimiter','tab');
  127. fprintf('Done %d %f (%.2f,%.2f,%.2f)/(%.2f,%.2f,%.2f)\n',...
  128. i,chi2,x0(1),x0(2),x0(3),x1(1),x1(2),x1(3));
  129. [x0,ul,ub]=generateInitialValues(valueGeneratorSettings);
  130. end
  131. %this is the result that will be used by k1 calculator
  132. sigmaCode=sprintf('%.2f',sigma2);
  133. sigmaCode=strrep(sigmaCode,'.','p');
  134. code=sprintf('%s_%d_%s_Pixel',patientID,nclass,sigmaCode);
  135. ofile=fullfile(path,patientID,sprintf('%s_fitParFinal.txt',code));
  136. writematrix([fmin x qfitmin],ofile,'Delimiter','tab');
  137. %ofile=fullfile(path,sprintf('CIFinal_%d_%d.txt',nclass,realizationId));
  138. %writematrix(fci,ofile,'Delimiter','tab');
  139. disp(sprintf('Found min at %d',imin));
  140. globalPar=[x(1:3) 0 0 0];
  141. cPars=reshape(qfitmin,[],nclass)';
  142. %reset k1 for those where BVF is nearly one
  143. %cPars(cPars(:,2)>0.4,1)=0;
  144. %reset k1 for those where k2 is abnormally large
  145. %cPars(cPars(:,3)>1,1)=0;
  146. opath=fullfile(path,patientID);
  147. plotFunctions(opath,code,globalPar,cPars,cax,centers);
  148. end