3 # The latest update : %G% at %U%
5 #%Z% lctfDetermination ver %I%
8 #%Z% Usage : lctfDetermination
12 static char __sccs_id[] = "%Z%lctfDetermination ver%I%; Date:%D% %Z%";
16 #include "./lctfDetermination.h"
23 Henderson-like Min-Max Method
24 0.9<CTF*CTF: +Scattering : Score
25 CTF*CTF<0.1: -Scattering : Penalty
29 lctfDeterminationbyMinMaxMethods(ctfInfo* res, mrcImage* mrc, ctfInfo* ini, long mode)
39 scatter = lmrcFSInfoScatteringAngularDistributionAverage(mrc);
40 spacing = lmrcFSInfoSpacing(mrc);
41 DEBUGPRINT2("%f %f\n", scatter->data[1], spacing->data[1]);
42 ctf = floatVectorInit(NULL, spacing->size);
48 for(tmp.defocus=0; tmp.defocus<2*ini->defocus; tmp.defocus+=ini->defocus/100.0) {
49 for(i=0; i<spacing->size; i++) {
50 ctf->data[i] = ctfFunction(&tmp, spacing->data[i], mode);
52 DEBUGPRINT1("%f\n", ctf->data[1]);
54 for(i=0; i<spacing->size; i++) {
55 if(tmp.CutLow < spacing->data[i]
56 &&spacing->data[i] < tmp.CutHigh ) {
57 if(SQR(ctf->data[i])>0.9) {
58 E += scatter->data[i];
59 } else if(SQR(ctf->data[i])<0.1) {
60 E -= scatter->data[i];
65 fprintf(stdout, "Max: %f %f %f\n", tmp.defocus, E, maxE);
67 res->defocus = tmp.defocus;
69 fprintf(stdout, "%10.6e %10.6e\n", tmp.defocus, E);
76 F(R) = S(R)*S(R) + N(R)*N(R) + N2(R)*N2(R)
78 S(R) = I0*|CTF(R)|*Env(R)*ME(R)*Vib(R)*MTF(R) ,
79 N(R) = I0*White*MTF(R) and
83 A : Normalization Factor
84 CTF : -sin(Kai)-a*cos(Kai)
85 Kai = M_PI*dF*lambda*R*R - 0.5*M_PI*Cs*lambda*lambda*lambda*R*R*R*R
86 ENV(Cs) : exp(-SQR(M_PI*Cs*lambda*lambda*R*R*R-M_PI*dF*R)*SQR(Ain)/log(2))
87 ENV(Cc) : exp(-SQR(M_PI*lambda*R*R*Cc*dE/E*((1+E/E0)/(1+E/E0/2))/4/sqrt(log(2))))
89 SN : constant (White Noise)
90 B : constant (MTF) SingleExp/Lorenzian/Both
92 a[1] : I0 : normarizing factor
93 a[2] : dF : defocus (underfocus is positive)
95 a[4] : a : the ratio of amplitude contrast to phase contrast
96 a[5] : Ai : Illumination angle
99 a[8] : V : Vibration : exp(-V*V*R*R/2)
100 a[9] : White : signal to noise ratio
101 a[10] : White2 : signal to noise ratio
102 a[11] : B : Dumping Factor of MTF: exp(-B*R)
103 a[12] : E : Energy : fixed
104 a[13] : E0 : Energy : fixed
105 a[14] : lambda : Wave Length : fixed
106 a[15] : Me : Scattering Factor : fixed
109 static ctfInfo __lctfDetermineCTF;
113 angularDistributionFunctionOfSignalAndNoise(float x, float p[], float* y, float dyda[], int na)
115 float R, I0, dF, Cs, a, Ai, Cc, dE, V, White, White2, B, E, E0, lambda, Me;
116 float chi, dchidR, dchi, spread, dspread, CTF, dCTF, Env1, Env2, Env, Vib, MTF;
137 if(__lctfDetermineCTF.flagMolecEnvTable) {
138 Me = lmolecularEnvelopeDataGet(&(__lctfDetermineCTF.MolecEnvTable), R*1e-10, 0);
140 Me = exp(-p[12]*p[12]*R*R/2.0);
148 chi = M_PI*(dF*lambda - 0.5*Cs*lambda*lambda*lambda*R*R)*R*R;
149 dchidR = 2*M_PI*(dF*lambda - Cs*lambda*lambda*lambda*R*R)*R;
150 dchi = M_PI*(Cs*lambda*lambda*R*R - dF)*R;
151 spread = M_PI*lambda*R*R*Cc*dE/E*((1+E/E0)/(1+E/E0/2))/4/sqrt(log(2));
152 CTF = -sin(chi) - a*cos(chi);
153 Env1 = exp(-SQR(dchi)*SQR(Ai)/log(2));
154 Env2 = exp(-SQR(spread));
156 Vib = exp(-V*V*R*R/2.0);
159 S = I0*Me*CTF*Env*Vib*MTF;
163 F = SQR(S) + SQR(N) + SQR(N2);
168 dyda[2] = 2*S*I0*Me*(-cos(chi)+a*sin(chi))*(M_PI*lambda*R*R)*Env*Vib*MTF
169 +2*S*S*(-2)*dchi*(-M_PI*R)*SQR(Ai)/log(2);
170 dyda[3] = 2*S*I0*Me*(-cos(chi)+a*sin(chi))*(M_PI*(-0.5)*lambda*lambda*lambda*R*R*R*R)*Env*Vib*MTF
171 +2*S*S*(-2)*dchi*(M_PI*lambda*lambda*R*R*R)*SQR(Ai)/log(2);
172 dyda[4] = 2*S*I0*Me*(-cos(chi))*Env*Vib*MTF;
173 dyda[5] = 2*S*S*(-2)*SQR(dchi)*Ai/log(2);
174 dyda[6] = 2*S*S*(-2)*spread*M_PI*lambda*R*R* dE/E*((1+E/E0)/(1+E/E0/2))/4/sqrt(log(2));
175 dyda[7] = 2*S*S*(-2)*spread*M_PI*lambda*R*R*Cc /E*((1+E/E0)/(1+E/E0/2))/4/sqrt(log(2));
176 dyda[8] = S*S*(-1)*V*R*R;
177 dyda[9] = 2*N *N /White;
178 dyda[10]= 2*N2*N2/White2;
179 dyda[11]= 2*(S*S+N*N)*(-R);
181 if(__lctfDetermineCTF.flagMolecEnvTable) {
184 dyda[12] = 2*S*S*(-p[12]*R*R);
186 DEBUGPRINT6("%e %e %e %e %e %e ", dyda[1], dyda[2], dyda[3], dyda[4], dyda[5], dyda[6]);
187 DEBUGPRINT6("%e %e %e %e %e %e \n", dyda[7], dyda[8], dyda[9], dyda[10], dyda[11], dyda[12]);
192 if(__lctfDetermineCTF.flagMolecEnvTable) {
195 (I0*Me*((-cos(chi)+a*sin(chi))*dchidR)*Env*Vib*MTF
196 + I0*Me*CTF*((-2)*dchi*SQR(Ai)/log(2)*M_PI*(3*Cs*lambda*lambda*R - dF)*Env1)*Vib*MTF
197 + I0*Me*CTF*((-2)*spread*2*M_PI*lambda*R*Cc*dE/E*((1+E/E0)/(1+E/E0/2))/4/sqrt(log(2))*Env2)*Vib*MTF
198 + I0*Me*CTF*Env*(-V*V*R*Vib)*MTF
199 + I0*Me*CTF*Env*Vib*(-B*MTF))
204 (I0*(-V*V*R*Me)*CTF*Env*Vib*MTF
205 + I0*Me*((-cos(chi)+a*sin(chi))*dchidR)*Env*Vib*MTF
206 + I0*Me*CTF*((-2)*dchi*SQR(Ai)/log(2)*M_PI*(3*Cs*lambda*lambda*R*R - dF)*Env1)*Env2*Vib*MTF
207 + I0*Me*CTF*Env1*((-2)*spread*2*M_PI*lambda*R*Cc*dE/E*((1+E/E0)/(1+E/E0/2))/4/sqrt(log(2))*Env2)*Vib*MTF
208 + I0*Me*CTF*Env*(-V*V*R*Vib)*MTF
209 + I0*Me*CTF*Env*Vib*(-B*MTF))
215 lctfDeterminationbyFittingMethods(ctfInfo* res, ctfInfo* var, mrcImage* mrc, ctfInfo* ini, long mode)
218 floatVector* scatter;
219 floatVector* spacing;
222 long i, j, imin, imax, n, flag;
232 float alambda, oldalambda;
234 scatter = lmrcFSInfoScatteringAngularDistributionAverage(mrc);
235 sig = lmrcFSInfoScatteringAngularDistributionSD(mrc);
236 spacing = lmrcFSInfoSpacing(mrc);
237 ctf = floatVectorInit(NULL, spacing->size);
238 imin = 0; imax = spacing->size - 1; n = 0;
239 for(i=0; i<spacing->size; i++) {
240 if(ini->CutLow <= spacing->data[i]
241 &&ini->CutHigh >= spacing->data[i]) {
247 spacing->data[i] = spacing->data[i]*1e10 ;
248 DEBUGPRINT4("%d: %g %g %g\n", i, spacing->data[i], scatter->data[i], sig->data[i]);
251 fprintf(stderr, "mrcImage is too small : %d!!\n", n);
254 DEBUGPRINT4("Low: %g High: %g ::: n: %d, imin: %d\n", ini->CutLow, ini->CutHigh, n, imin);
261 covar = matrix(1, ma, 1, ma);
262 alpha = matrix(1, ma, 1, ma);
264 for(i=1; i<=ma; i++) {
267 for(j=1; j<=ma; j++) {
273 a[1] = ini->I0; ia[1] = 1;
274 a[2] = ini->defocus*1e-10; ia[2] = 1;
275 a[3] = ini->Cs*1e-3; ia[3] = 1;
276 a[4] = ini->ratioOfAmpToPhase; ia[4] = 1;
277 a[5] = ini->Ain*1e-3; ia[5] = 1;
278 a[6] = ini->Cc*1e-3; ia[6] = 1;
279 a[7] = ini->dE; ia[7] = 1;
280 a[8] = ini->BofVibration*1e-10; ia[8] = 1;
281 a[9] = ini->WhiteNoise; ia[9] = 1;
282 a[10]= ini->WhiteNoise2; ia[10] = 1;
283 a[11]= ini->BofMTF*1e-10; ia[11] = 1;
284 if(ini->flagMolecEnvTable) {
285 a[12]= 0; ia[12] = 0;
287 a[12]= ini->MolecEnv*1e-10; ia[12] = 1;
290 a[13] = ini->kV*1e3; ia[13] = 0;
291 a[14] = 511*1e3; ia[14] = 0;
292 a[15] = wavelengthOfElectron(ini->kV*1e3); ia[15] = 0;
293 fprintf(stderr, "lambda: %g\n", a[15]);
295 a[16] = ini->Magnification; ia[16] = 1;
297 __lctfDetermineCTF = *ini;
301 for(count=0; count<20; count++) {
302 fprintf(stdout, "count: %d\n", count); fflush(stdout);
303 mrqmin(spacing->data+imin-1, scatter->data+imin-1, sig->data+imin-1, n, a, ia, ma, covar, alpha, &chisq, angularDistributionFunctionOfSignalAndNoise, &alambda);
304 fprintf(stdout, "chisq: %15.6g\n", chisq);
305 fprintf(stdout, "alambda: %15.6g\n", alambda);
306 for(i=1; i<=ma; i++) {
307 fprintf(stdout, "a[%d]: %15.6g\n", i, a[i]);
311 } else if(oldalambda<alambda) {
314 oldalambda = alambda;
317 fprintf(stdout, "Fitting End: %15.6g\n", chisq);
319 res->defocus = a[2]*1e10;
321 res->ratioOfAmpToPhase = a[4];
322 res->Ain = a[5]*1e+3;
325 res->BofVibration = a[8]*1e10;
326 res->WhiteNoise = a[9];
327 res->WhiteNoise2 = a[10];
328 res->BofMTF = a[11]*1e10;
329 if(ini->flagMolecEnvTable) {
331 res->MolecEnv = a[12]*1e10;
333 res->Magnification = a[16];
336 mrqmin(spacing->data+imin-1, scatter->data+imin-1, sig->data+imin-1, n, a, ia, ma, covar, alpha, &chisq, angularDistributionFunctionOfSignalAndNoise, &alambda);
337 fprintf(stdout, "chisq: %15.6g\n", chisq);
338 fprintf(stdout, "alambda: %15.6g\n", alambda);
339 for(i=1; i<=ma; i++) {
340 fprintf(stdout, "a[%d]: %15.6g\n", i, a[i]);
342 var->I0 = sqrt(covar[1][1]);
343 var->defocus = sqrt(covar[2][2])*1e10;
344 var->Cs = sqrt(covar[3][3])*1e+3;
345 var->ratioOfAmpToPhase = sqrt(covar[4][4]);
346 var->Ain = sqrt(covar[5][5])*1e+3;
347 var->Cc = sqrt(covar[6][6])*1e+3;
348 var->dE = sqrt(covar[7][7]);
349 var->BofVibration = sqrt(covar[8][8])*1e10;
350 var->WhiteNoise = sqrt(covar[9][9]);
351 var->WhiteNoise2 = sqrt(covar[10][10]);
352 var->BofMTF = sqrt(covar[11][11])*1e10;
353 if(ini->flagMolecEnvTable) {
355 res->MolecEnv = sqrt(covar[12][12])*1e10;
357 var->Magnification = sqrt(covar[16][16]);
362 ThonRing Point: ScatteringDifferential :0 score+
367 determination MaximumValue :return +1
368 or minimumValue :return -1
369 NotLimitValue :return 0
372 static int __LimitValue(floatVector* function,long i,long around)
374 float before = 0.0,after = 0.0;
379 //while(before == 0.0){
380 before =function->data[i]-function->data[j];
385 //while(after == 0.0){
386 after =function->data[j]-function->data[i];
398 else if(before < 0.0){
417 static int __SquareLimitValue(floatVector* function,long i,long around)
419 float before = 0.0,after = 0.0;
424 //while(before == 0.0){
425 before = SQR(function->data[i])-SQR(function->data[j]);
430 //while(after == 0.0){
431 after = SQR(function->data[j])-SQR(function->data[i]);
434 //fprintf(stdout,"%ld %f %f ",i,before,after);
445 else if(before < 0.0){
462 //fprintf(stdout,"%ld\n",flag);
467 static float __Median(floatVector* function, long i, long around){
469 float sequence[around*2 + 1];
474 for(j=i-around;j<=i+around;j++){
475 sequence[k] = function->data[j];
479 for(j=0;j<around*2+1;j++){
480 for(k=j+1;k<around*2+1;k++){
481 if(sequence[j]>sequence[k]){
483 sequence[j] = sequence[k];
488 return(sequence[around]);
491 static float __Average(floatVector* function,long i,long around){
496 for(j=i-around;j<=i+around;j++){
497 sum += function->data[j];
500 return(sum/(around*2+1));
504 static long __LongAbs(long x){
513 static float __AverageWithWeight(floatVector* function,long i,long around){
519 for(j=i-around;j<=i+around;j++){
520 sum += function->data[j]/(__LongAbs(i-j)+1);
521 n += (float)1/( __LongAbs(i-j) + 1);
528 /*Smoothing is CurveSmoothing
529 mode 1: for MedianMethod
530 mode 2: for AverageMethod
531 mode 3: for AverageMethod with Weight
533 void __Smoothing(floatVector* function,floatVector* SmoothCurve ,long around,long mode){
540 for(i=0;i<function->size;i++){
542 if(i!=0 && i!=function->size-1){
546 else if(i>function->size-1-around){
547 aroundtmp = function->size-1-i;
552 SmoothCurve->data[i] = __Median(function,i,aroundtmp);
556 SmoothCurve->data[i] = __Average(function,i,aroundtmp);
560 SmoothCurve->data[i] = __AverageWithWeight(function,i,aroundtmp);
567 SmoothCurve->data[i] = function->data[i];
575 lctfDeterminationbyDifferentialMethods(ctfInfo* res, mrcImage* mrc, ctfInfo* ini,long* MaxThonRing, long mode)
577 floatVector* scatter;
578 floatVector* spacing;
580 floatVector* MedianCurve;
582 long Differentialaround;
588 float ME; /*M......with MedianCurve*/
594 Differentialaround = 1;
598 scatter = lmrcFSInfoScatteringAngularDistributionAverage(mrc);
599 spacing = lmrcFSInfoSpacing(mrc);
600 DEBUGPRINT2("%f %f\n", scatter->data[1], spacing->data[1]);
601 ctf = floatVectorInit(NULL, spacing->size);
606 fprintf(stdout,"\nDifferentialMethod\n");
607 MedianCurve = floatVectorInit(NULL,spacing->size);
608 for(tmp.defocus = 0.0; tmp.defocus<2*ini->defocus; tmp.defocus+=ini->defocus/1000.0) {
609 for(i=0;i<spacing->size;i++){
610 ctf->data[i] = ctfFunction(&tmp, spacing->data[i],mode);
612 __Smoothing(scatter,MedianCurve,Smootharound,Smoothmode);
613 DEBUGPRINT1("%f\n", ctf->data[1]);
617 for(i=(0+Differentialaround); i<(spacing->size-Differentialaround); i++) {
618 if(tmp.CutLow < spacing->data[i]
619 &&spacing->data[i] < tmp.CutHigh ) {
620 /*DifferentialMethod*/
621 if(__SquareLimitValue(ctf,i,Differentialaround) == -1){
623 if(__LimitValue(scatter,i,Differentialaround) == -1){
630 if(__LimitValue(MedianCurve,i,Differentialaround) == -1){
641 fprintf(stdout, "Max: %10.6e %f %f\n", tmp.defocus, E, maxE);
643 res->defocus = tmp.defocus;
647 //fprintf(stdout, "MMAX: %f %f %f\n", tmp.defocus,ME,MmaxE);
649 Mres.defocus = tmp.defocus;
650 *MaxThonRing = ThonRing;
652 //fprintf(stdout, "%10.6e %3ld %3.0f %3.0f\n", tmp.defocus,ThonRing, E,ME);
654 fprintf(stdout,"defocus(not median)= %10.6f (median)= %10.6f\n",res->defocus,Mres.defocus);
656 res->defocus = Mres.defocus;
658 /*for(i=0;i<spacing->size;i++){
659 ctf->data[i] = ctfFunction(&Mres, spacing->data[i],mode);
661 fprintf(stdout,"\n\ndefocus:%f\n",Mres.defocus);
662 fprintf(stdout," spacing: SQR(ctf): scatter:\n");
663 for(i=0;i<spacing->size;i++){
665 if(tmp.CutLow < spacing->data[i]
666 &&spacing->data[i] < tmp.CutHigh ) {
667 fprintf(stdout,"%10.6e %10.6e %10.6e ",spacing->data[i],SQR(ctf->data[i]),scatter->data[i]);
668 if(__SquareLimitValue(ctf,i,Differentialaround) == -1){
669 fprintf(stdout,"ring\n");
672 fprintf(stdout,"\n");
678 void __MinSquare(floatVector* functionX,floatVector* functionY,floatVector* MinSquare,long around){
690 for(i=around;i<functionX->size-around;i++){
696 else if(functionX->size-1-i<around){
697 tmpAround = functionX->size-1-i;
700 if(i!=0 || i!=functionX->size-1){
705 for(j=i-around;j<=i+around;j++){
706 x += functionX->data[j];
707 y += functionY->data[j];
708 xy += functionX->data[j]*functionY->data[j];
709 xx += functionX->data[j]*functionX->data[j];
711 MinSquare->data[i] = (n*xy-x*y)/(n*xx-x*x);
714 MinSquare->data[i] = 0.0;
719 void __MinimumByMinSquare(floatVector* functionX,floatVector* functionY,floatVector* Minimum,long around)
721 floatVector* MinSquare;
726 MinSquare = floatVectorInit(NULL,functionX->size);
727 __MinSquare(functionX,functionY,MinSquare,around);
729 for(i=0;i<functionX->size;i++){
730 if(MinSquare->data[i] > 0.0){
731 MinSquare->data[i] = 1.0;
733 else if(MinSquare->data[i] < 0.0){
734 MinSquare->data[i] = -1.0;
739 for(i=1;i<functionX->size;i++){
740 switch ((int)MinSquare -> data[i-1]){
742 switch ((int)MinSquare->data[i]){
744 Minimum->data[i] = 1.0;
748 Minimum->data[i] = 0.0;
753 while(MinSquare->data[i+j] == 0.0 ){
754 if(i+j == functionX->size){
760 if(MinSquare->data[i+j] > 0){
761 Minimum->data[i] == 1.0;
763 else if(MinSquare->data[i+j] < 0){
764 Minimum->data[i] == 0.0;
773 Minimum->data[i] == 0.0;
779 while(MinSquare->data[i+j] == 0.0){
786 if(MinSquare->data[i+j] > 0.0){
787 Minimum->data[i] == 0.0;
789 else if(MinSquare->data[i+j] <= 0.0){
791 while(MinSquare->data[i+k] == 0.0){
792 if(i+k == functionX->size){
798 if(MinSquare->data[i+k] >= 0.0){
799 Minimum->data[i] = 1.0;
802 Minimum->data[i] = 0.0;
812 lctfDeterminationbyMinSquareMethods(ctfInfo* res, mrcImage* mrc, ctfInfo* ini,long* MaxThonRing, long mode)
814 floatVector* scatter;
815 floatVector* spacing;
818 floatVector* MedianCurve3;
819 floatVector* MedianCurve5;
820 floatVector* MedianCurve7;
821 floatVector* MinSquare;
822 floatVector* Minimum;
823 floatVector* ThonRing;
824 floatVector* ctfMinSquare;
826 long Differentialaround;
832 float ME; /*M......with MedianCurve*/
837 Differentialaround = 1;
840 scatter = lmrcFSInfoScatteringAngularDistributionAverage(mrc);
841 spacing = lmrcFSInfoSpacing(mrc);
842 DEBUGPRINT2("%f %f\n", scatter->data[1], spacing->data[1]);
843 ctf = floatVectorInit(NULL, spacing->size);
844 ctfSQR = floatVectorInit(NULL, spacing->size);
845 ThonRing= floatVectorInit(NULL, spacing->size);
846 ctfMinSquare = floatVectorInit(NULL,spacing->size);
851 fprintf(stdout,"\nDifferentialMethod\n");
852 MedianCurve3 = floatVectorInit(NULL,spacing->size);
853 MedianCurve5 = floatVectorInit(NULL,spacing->size);
854 MedianCurve7 = floatVectorInit(NULL,spacing->size);
855 MinSquare = floatVectorInit(NULL,spacing->size);
856 Minimum = floatVectorInit(NULL,spacing->size);
858 __Smoothing(scatter,MedianCurve3,1,1);
859 __Smoothing(scatter,MedianCurve5,2,1);
860 __Smoothing(scatter,MedianCurve7,3,1);
862 __MinimumByMinSquare(spacing,MedianCurve5,Minimum,2);
863 __MinSquare(spacing,MedianCurve5,MinSquare,2);
865 for(tmp.defocus = 0.0; tmp.defocus<2*ini->defocus; tmp.defocus+=ini->defocus/1000.0) {
866 for(i=0;i<spacing->size;i++){
867 ctf->data[i] = ctfFunction(&tmp, spacing->data[i],mode);
869 DEBUGPRINT1("%f\n", ctf->data[1]);
873 for(i=(0+Differentialaround); i<(spacing->size-Differentialaround); i++) {
874 if(tmp.CutLow < spacing->data[i]
875 &&spacing->data[i] < tmp.CutHigh ) {
877 /*DifferentialMethod*/
878 if(__SquareLimitValue(ctf,i,Differentialaround) == -1){
880 if(/*__LimitValue(MedianCurve5,i,Differentialaround)*/Minimum->data[i] == 1){
894 fprintf(stdout, "MMAX: %f %f %f\n", tmp.defocus,ME,MmaxE);
896 res->defocus = tmp.defocus;
897 *MaxThonRing = ThonRingSize;
899 //fprintf(stdout, "%10.6e %3ld %3.0f %3.0f\n", tmp.defocus,ThonRingSize, E,ME);
901 fprintf(stdout,"defocus(median)= %10.6f\n",res->defocus);
904 for(i=0;i<spacing->size;i++){
905 ctf->data[i] = ctfFunction(res, spacing->data[i],mode);
906 ctfSQR->data[i] = SQR(ctf->data[i]);
908 __MinimumByMinSquare(spacing,ctfSQR,ThonRing,1);
909 __MinSquare(spacing,ctfSQR,ctfMinSquare,1);
910 fprintf(stdout,"\n\ndefocus:%f\n",res->defocus);
911 fprintf(stdout," spacing: SQR(ctf): scatter: Median: MinSquare: Minimum:\n");
912 for(i=0;i<spacing->size;i++){
914 if(tmp.CutLow < spacing->data[i]
915 &&spacing->data[i] < tmp.CutHigh ) {
916 fprintf(stdout,"%10.6e %10.6e %10.6e %10.6e %+10.6e %f %+10.6e %f ",spacing->data[i],SQR(ctf->data[i]),scatter->data[i],MedianCurve5->data[i],MinSquare->data[i],Minimum->data[i],ctfMinSquare->data[i],ThonRing->data[i]);
917 if(__SquareLimitValue(ctf,i,Differentialaround) == -1){
918 fprintf(stdout,"ring\n");
921 fprintf(stdout,"\n");
928 /*ctfDeterminationbyCovarianceMethod*/
930 static float __Covariance(floatVector* function,floatVector* MedianCurve,long i,long around){
936 for(j=(i-around);j<=(i+around);j++){
937 tmp += SQR(MedianCurve->data[j] - function->data[j]);
944 void __CovarianceEstimation(floatVector* function,floatVector* MedianCurve,floatVector* Covariance,long around){
951 for(i=0;i<function->size;i++){
953 if(i!=0 && i!=function->size-1){
957 else if(i>function->size-1-around){
958 aroundtmp = function->size-1-i;
961 Covariance->data[i] = __Covariance(function,MedianCurve,i,aroundtmp);
966 Covariance->data[i] = 0.0;
974 lctfDeterminationbyCovarianceMethods(ctfInfo* res, mrcImage* mrc, ctfInfo* ini,long* MaxThonRing, long mode)
976 floatVector* scatter;
977 floatVector* spacing;
979 floatVector* MedianCurve;
980 floatVector* Covariance;
982 long Differentialaround;
984 long CovarianceAround;
990 Differentialaround = 1;
992 CovarianceAround = 2;
994 scatter = lmrcFSInfoScatteringAngularDistributionAverage(mrc);
995 spacing = lmrcFSInfoSpacing(mrc);
996 DEBUGPRINT2("%f %f\n", scatter->data[1], spacing->data[1]);
997 ctf = floatVectorInit(NULL, spacing->size);
1001 MedianCurve = floatVectorInit(NULL,spacing->size);
1002 Covariance = floatVectorInit(NULL,spacing->size);
1004 fprintf(stdout,"\nCovarianceMethod\n");
1005 if(*MaxThonRing == -1){
1006 fprintf(stdout,"all ThonRing search\n");
1009 fprintf(stdout,"only ThonRing = %3ld\n",*MaxThonRing);
1012 for(tmp.defocus = 0.0; tmp.defocus<2*ini->defocus; tmp.defocus+=ini->defocus/1000.0) {
1013 for(i=0;i<spacing->size;i++){
1014 ctf->data[i] = ctfFunction(&tmp, spacing->data[i],mode);
1016 __Smoothing(scatter,MedianCurve,Smootharound,1);
1017 __CovarianceEstimation(scatter,MedianCurve,Covariance,CovarianceAround);
1018 DEBUGPRINT1("%f\n", ctf->data[1]);
1021 for(i=(0+Differentialaround); i<(spacing->size-Differentialaround); i++) {
1022 if(tmp.CutLow < spacing->data[i]
1023 &&spacing->data[i] < tmp.CutHigh ) {
1024 if(__SquareLimitValue(ctf,i,Differentialaround) == -1){
1027 E += log10(Covariance->data[i] + 1.0);
1034 //E = E/(float)ThonRing;
1035 if((minE > E || minE == 0.0) && (*MaxThonRing == ThonRing || *MaxThonRing == -1) ){
1036 fprintf(stdout, "minE: %10.6e %10.6e %10.6e\n", tmp.defocus,E,minE);
1038 res->defocus = tmp.defocus;
1041 fprintf(stdout, "%10.6e %3ld %10.6e \n", tmp.defocus,ThonRing, E);
1043 fprintf(stdout,"defocus= %10.6f\n",res->defocus);
1046 for(i=0;i<spacing->size;i++){
1047 ctf->data[i] = ctfFunction(res, spacing->data[i],mode);
1049 fprintf(stdout,"\n\ndefocus:%f\n",res->defocus);
1050 fprintf(stdout," spacing: SQR(ctf): scatter: Median: Estimation:\n");
1051 for(i=0;i<spacing->size;i++){
1053 if(tmp.CutLow < spacing->data[i]
1054 &&spacing->data[i] < tmp.CutHigh ) {
1055 fprintf(stdout," %10.6e %10.6e %10.6e %10.6e %10.6e ",spacing->data[i],SQR(ctf->data[i]),scatter->data[i],MedianCurve->data[i],Covariance->data[i]);
1056 if(__SquareLimitValue(ctf,i,Differentialaround) == -1){
1057 fprintf(stdout,"ring\n");
1060 fprintf(stdout,"\n");
1068 lctfDeterminationbyMixMethods(ctfInfo* res, mrcImage* mrc, ctfInfo* ini,long* ThonRing, long mode){
1070 fprintf(stdout,"\nDifferential & Covariance Method");
1071 lctfDeterminationbyDifferentialMethods(res, mrc, ini,ThonRing, mode);
1073 lctfDeterminationbyCovarianceMethods(res,mrc,ini,ThonRing,mode);