| Bsoft 1.9 Bernard's software package

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

img_ctf.cpp
Go to the documentation of this file.
1
9 #include "Bimage.h"
10 #include "ctf.h"
11 #include "img_ctf.h"
12 #include "simplex.h"
13 #include "moving_average.h"
14 #include "Matrix.h"
15 #include "matrix_linear.h"
16 #include "utilities.h"
17
18 // Declaration of global variables
19 extern int verbose; // Level of output to the screen
20
21 // Internal function prototypes
22 double img_ctf_fit_astigmatism_new(Bimage* p, CTFparam* em_ctf, double lores, double hires);
23 double ctf_fit_baseline(Bimage* prad, double real_size, CTFparam* em_ctf, double lores, double hires);
24 double ctf_fit_envelope(Bimage* prad, double real_size, CTFparam* em_ctf, double lores, double hires);
25 double ctf_fit_eman_to_baseline(long n, double* x, double* y, double* coeff);
26 double eman_baseline_R(Bsimplex* simp);
27 double ctf_fit_gaussian(long n, double* x, double* y, double* coeff);
28 double gaussian_R(Bsimplex* simp);
29 double ctf_fit_double_gaussian_baseline(long n, double* x, double* y, double* coeff);
30 double ctf_fit_double_gaussian_envelope(long n, double* x, double* y, double* coeff);
31 double double_gaussian_R(Bsimplex* simp);
32
55 Bimage* img_ctf_calculate(CTFparam cp, int action, double wiener, Vector3<long> size,
56 Vector3<double> sampling, double lores, double hires)
57 {
58 if ( cp.check_defocus() || cp.check_Cs() ) {
59 cerr << "in img_ctf_calculate" << endl;
60 return NULL;
61 }
62
63 if ( lores < 0 ) lores = 0;
64 if ( hires <= 0 ) hires = sampling.x();
65 if ( lores > 0 && lores < hires ) swap(lores, hires);
66
67 double shi(1/hires);
68 double slo = (lores > 0)? 1/lores: 0;
69
70 Bimage* p = new Bimage(Float, TSimple, size, 1);
71 if ( sampling.volume() > 0 ) p->sampling(sampling);
72
73 long i, n, x, y, z, sign;
74 double sx, sy, sz, s, s2, w, ctf_fac, base, env, ctf_env;
75 Vector3<double> freq_scale(1.0/p->real_size());
76 Vector3<double> h((p->sizeX() - 1)/2, (p->sizeY() - 1)/2, (p->sizeZ() - 1)/2);
77
78 Bstring base_eq = cp.baseline_equation();
79 Bstring env_eq = cp.envelope_equation();
80
81 if ( verbose & ( VERB_LABEL | VERB_PROCESS ) ) {
82 cout << "Calculating a CTF function:" << endl;
83 switch ( action ) {
84 case 1: cout << "Flipping phases" << endl; break;
85 case 2: cout << "Applying a CTF" << endl; break;
86 case 3: cout << "Correcting for the CTF" << endl; break;
87 case 4: cout << "Correcting for the CTF with an optimal Wiener filter" << endl; break;
88 case 5: cout << "Correcting for the CTF with baseline enhancement" << endl; break;
89 case 6: cout << "Correcting for the CTF with baseline2 enhancement" << endl; break;
90 case 7: cout << "Flipping phases with baseline enhancement" << endl; break;
91 case 8: cout << "Correcting for the CTF with baseline3 enhancement" << endl; break;
92 // case 9: cout << "Applying theoretical envelopes" << endl; break;
93 // case 10: cout << "Applying a CTF with theoretical envelopes" << endl; break;
94 default: break;
95 }
96 }
97 if ( verbose & VERB_PROCESS ) {
98 cp.show();
99 cout << "Resolution range: " << hires << " - ";
100 if ( lores > 0 ) cout << lores << " A" << endl;
101 else cout << "inf A" << endl;
102 if ( action == 3 || action == 5 || action == 6 )
103 cout << "Wiener factor: " << wiener << endl;
104 if ( action >= 4 ) {
105 cout << "Envelope: " << env_eq << endl;
106 cout << "Noise: " << base_eq << endl;
107 }
108 cout << endl;
109 }
110
111 for ( i=n=0; n<p->images(); n++ ) {
112 for ( z=0; z<p->sizeZ(); z++ ) {
113 sz = z;
114 if ( z > h.z() ) sz -= p->sizeZ();
115 sz *= freq_scale.z();
116 for ( y=0; y<p->sizeY(); y++ ) {
117 sy = y;
118 if ( y > h.y() ) sy -= p->sizeY();
119 sy *= freq_scale.y();
120 for ( x=0; x<p->sizeX(); x++, i++ ) {
121 sx = x;
122 if ( x > h.x() ) sx -= p->sizeX();
123 sx *= freq_scale.x();
124 s2 = sx*sx + sy*sy + sz*sz;
125 s = sqrt(s2);
126 if ( s >= slo && s <= shi ) {
127 ctf_fac = cp.calculate(s2, atan2(sy,sx));
128 w = 0;
129 sign = ( ctf_fac < 0 )? -1: 1;
130 if ( action > 3 ) base = cp.calc_baseline(s);
131 switch ( action ) {
132 case 1: w = sign; break; // Flip the phase
133 case 2: w = ctf_fac; break; // Apply the CTF
134 case 3:
135 w = ctf_fac/(ctf_fac*ctf_fac + wiener);
136 break; // Spider method
137 case 4:
138 if ( base > 0 ) {
139 env = cp.calc_envelope(s);
140 ctf_env = ctf_fac*env;
141 // w = ctf_env/(ctf_fac*ctf_env + base);
142 w = ctf_fac*sqrt(env)/(ctf_fac*ctf_env + base);
143 // w = ctf_fac*sqrt(env/(ctf_fac*ctf_env + base));
144 }
145 break; // Wiener filter method
146 case 5:
147 w = ctf_fac/(ctf_fac*ctf_fac*base + wiener);
148 break; // Baseline enhancement
149 case 6:
150 // w = 1/(base*(ctf_fac + sign*wiener));
151 w = 1/(ctf_fac*base + sign*wiener);
152 break; // Baseline enhancement
153 case 7:
154 if ( base > 0 ) w = sign/sqrt(base);
155 break; // Flip phase with baseline enhancement
156 case 8:
157 env = cp.calc_envelope(s);
158 w = sign/sqrt(ctf_fac*ctf_fac*env + base);
159 // w = ctf_fac/sqrt(ctf_fac*ctf_fac*env + base);
160 // w = ctf_fac/(ctf_fac*ctf_fac*env + base);
161 break; // Baseline enhancement
162 default: break;
163 }
164 p->set(i, w);
165 }
166 }
167 }
168 }
169 }
170
171 p->statistics();
172
173 return p;
174 }
175
193 Bimage* img_wave_aberration(CTFparam cp, Vector3<int> size, Vector3<float> sampling)
194 {
195 Bimage* p = new Bimage(Float, TSimple, size, 1);
196 if ( sampling.volume() > 0 ) p->sampling(sampling);
197
198 unsigned long i, n, x, y, z;
199 double sx, sy, sz, s2;
200 Vector3<double> freq_scale(1.0/p->real_size());
201 Vector3<double> h((p->sizeX() - 1)/2, (p->sizeY() - 1)/2, (p->sizeZ() - 1)/2);
202
203 if ( verbose & VERB_PROCESS ) {
204 cout << "Calculating a wave aberration function:" << endl;
205 cout << "Defocus average & deviation: " << cp.defocus_average() << " A " << cp.defocus_deviation() << " A" << endl;
206 cout << "Astigmatism angle: " << cp.astigmatism_angle()*180/M_PI << " degrees" << endl;
207 cout << "Voltage: " << cp.volt() << " V" << endl;
208 cout << "Wavelength: " << cp.lambda() << " A" << endl;
209 cout << "Cs: " << cp.Cs() << " A" << endl;
210 cout << "Amplitude contrast: " << cp.amp_fac() << endl;
211 cout << endl;
212 }
213
214 for ( i=n=0; n<p->images(); n++ ) {
215 for ( z=0; z<p->sizeZ(); z++ ) {
216 sz = z;
217 if ( z > h.z() ) sz -= p->sizeZ();
218 sz *= freq_scale.z();
219 for ( y=0; y<p->sizeY(); y++ ) {
220 sy = y;
221 if ( y > h.y() ) sy -= p->sizeY();
222 sy *= freq_scale.y();
223 for ( x=0; x<p->sizeX(); x++, i++ ) {
224 sx = x;
225 if ( x > h.x() ) sx -= p->sizeX();
226 sx *= freq_scale.x();
227 s2 = sx*sx + sy*sy + sz*sz;
228 p->set(i, cp.delta_phi(s2, atan2(sy,sx)));
229 }
230 }
231 }
232 }
233
234 return p;
235 }
236
268 int img_ctf_apply(Bimage* p, CTFparam* em_ctf, int action, double wiener,
269 double lores, double hires)
270 {
271 if ( action < 1 || action > 10 ) return 0;
272
273 if ( wiener < 0.01 ) wiener = 0.01;
274
275 Bimage* pctf = img_ctf_calculate(*em_ctf, action, wiener, p->size(),
276 p->sampling(), lores, hires);
277
278 int back_transform(0);
279 if ( p->fourier_type() == NoTransform ) {
280 p->fft();
281 back_transform = 1;
282 }
283
284 long i, j, nn;
285
286 for ( nn=j=0; nn<p->images(); nn++ )
287 for ( i=0; i<p->image_size(); i++, j++ )
288 p->set(j, p->complex(j) * (*pctf)[i]);
289
290 delete pctf;
291
292 if ( back_transform ) p->fft(FFTW_BACKWARD);
293
294 p->statistics();
295
296 return 0;
297 }
298
299 int img_ctf_apply(Bimage* p, CTFparam* em_ctf, int action, double wiener,
300 double lores, double hires, fft_plan planf_2D, fft_plan planb_2D)
301 {
302 if ( action < 1 || action > 10 ) return 0;
303
304 if ( wiener < 0.01 ) wiener = 0.01;
305
306 Bimage* pctf = img_ctf_calculate(*em_ctf, action, wiener, p->size(),
307 p->sampling(), lores, hires);
308
309 int back_transform(0);
310 if ( p->fourier_type() == NoTransform ) {
311 p->fft(planf_2D, 1);
312 back_transform = 1;
313 if ( verbose & VERB_DEBUG )
314 cout << "DEBUG img_ctf_apply: image transformed" << endl;
315 }
316
317 long i, j, nn;
318
319 for ( nn=j=0; nn<p->images(); nn++ )
320 for ( i=0; i<p->image_size(); i++, j++ )
321 p->set(j, p->complex(j) * (*pctf)[i]);
322
323 delete pctf;
324
325 if ( back_transform ) {
326 p->fft(planb_2D, 1);
327 p->complex_to_real();
328 if ( verbose & VERB_DEBUG )
329 cout << "DEBUG img_ctf_apply: image back-transformed" << endl;
330 }
331
332 p->statistics();
333
334 return 0;
335 }
336
337 int img_ttf_apply_one(Bimage* p, long nn, CTFparam* ctf, int action,
338 double wiener, double def, double res_lo, double res_hi,
339 Vector3<long> psize, fft_plan planf, fft_plan planb)
340 {
341 verbose = 1;
342
343 CTFparam* ctf_temp = ctf->copy();
344
345 ctf_temp->defocus_average(def);
346
347 Bimage* pt = p->extract(nn);
348
349 pt->calculate_background();
350
351 Vector3<long> oldsize(pt->size()), translate;
352
353 pt->pad(psize);
354
355 img_ctf_apply(pt, ctf_temp, action, wiener, res_lo, res_hi, planf, planb);
356
357 pt->resize(oldsize, translate);
358
359 p->replace(nn, pt);
360
361 delete pt;
362 delete ctf_temp;
363
364 return 0;
365 }
366
379 int img_ctf_apply_to_proj(Bimage* proj, CTFparam* em_ctf, double defocus, double res_lo, double res_hi, fft_plan planf_2D, fft_plan planb_2D)
380 {
381 if ( !em_ctf ) return -1;
382
383 if ( verbose & VERB_DEBUG )
384 cout << "DEBUG img_ctf_apply_to_proj: def_avg=" << em_ctf->defocus_average() << endl;
385
386 CTFparam* ctf_temp = em_ctf->copy();
387
388 if ( defocus > 0 ) ctf_temp->defocus_average(defocus);
389
390 img_ctf_apply(proj, ctf_temp, 2, 0, res_lo, res_hi, planf_2D, planb_2D);
391
392 delete ctf_temp;
393
394 return 0;
395 }
396
431 int img_ttf_apply(Bimage* p, CTFparam* ctf, int action, double wiener,
432 Vector3<int> tile_size, double tilt, double axis, double res_lo, double res_hi)
433 {
434 if ( res_lo > 0 && res_lo < res_hi ) swap(res_lo, res_hi);
435
436 // Minimum and maximum tile sizes allowed
437 long min_size(64);
438 // long max_size(1024);
439 long max_size(2048);
440 Vector3<int> start;
441 Vector3<int> ext_size;
442
443 tile_size = tile_size.min(p->size());
444
445 tile_size = tile_size.max(min_size);
446 tile_size = tile_size.min(max_size);
447
448 tile_size = tile_size.min(p->size());
449
450 p->change_type(Float);
451
452 Bimage* pt = p->extract_tiles(0, tile_size);
453
454 long nn;
455 double ca(cos(axis)), sa(sin(axis)), tt(tan(tilt));
456 Vector3<double> coor;
457 double* d = new double[pt->images()];
458
459 // cout << p->image->origin() << endl;
460 // if ( verbose )
461 // cout << "Tile\tx\ty\t∆f" << endl;
462 for ( nn=0; nn<pt->images(); nn++ ) {
463 coor = (pt->image[nn].origin() + pt->size()/2 - p->image->origin()) * p->sampling(); // Center coordinates
464 d[nn] = ctf->defocus_average() + (coor.x()*sa - coor.y()*ca)*tt;
465 // if ( verbose )
466 // cout << n << tab << coor.x() << tab << coor.y() << tab << d[n]-ctf->defocus_average() << endl;
467 }
468 if ( verbose & VERB_FULL )
469 cout << ctf->defocus_average() << tab << d[0] << endl;
470 // bexit(0);
471
472 Bstring base_eq = ctf->baseline_equation();
473 Bstring env_eq = ctf->envelope_equation();
474
475 if ( verbose & ( VERB_LABEL | VERB_PROCESS ) ) {
476 cout << "Applying a tilted image transfer function:" << endl;
477 switch ( action ) {
478 case 1: cout << "Flipping phases" << endl; break;
479 case 2: cout << "Applying a CTF" << endl; break;
480 case 3: cout << "Correcting for the CTF" << endl; break;
481 case 4: cout << "Correcting for the CTF with an optimal Wiener filter" << endl; break;
482 case 5: cout << "Correcting for the CTF with baseline enhancement" << endl; break;
483 case 6: cout << "Correcting for the CTF with baseline2 enhancement" << endl; break;
484 case 7: cout << "Flipping phases with baseline enhancement" << endl; break;
485 case 8: cout << "Correcting for the CTF with baseline3 enhancement" << endl; break;
486 default: break;
487 }
488 }
489 if ( verbose & VERB_PROCESS ) {
490 cout << "Tile size: " << tile_size << endl;
491 cout << "Defocus range: " << d[0] << " - " << d[nn-1] << " (" << nn << ")" << endl;
492 cout << "Tilt angle and axis: " << tilt*180.0/M_PI << " " << axis*180.0/M_PI << endl;
493 ctf->show();
494 cout << "Resolution range: " << res_hi << " - ";
495 if ( res_lo > 0 ) cout << res_lo << " A" << endl;
496 else cout << "inf A" << endl;
497 if ( action == 3 || action == 5 || action == 6 )
498 cout << "Wiener factor: " << wiener << endl;
499 if ( action >= 4 ) {
500 cout << "Envelope: " << env_eq << endl;
501 cout << "Noise: " << base_eq << endl;
502 }
503 cout << endl;
504 }
505
506 long pad_factor(2);
507 long ft_size = findNextPowerOf((int)(pad_factor*pt->sizeX()), 2);
508 Vector3<long> psize(ft_size, ft_size, 1);
509
510 fft_plan planf = fft_setup_plan(psize, FFTW_FORWARD, 1);
511 fft_plan planb = fft_setup_plan(psize, FFTW_BACKWARD, 1);
512
513 #ifdef HAVE_GCD
514 dispatch_apply(pt->images(), dispatch_get_global_queue(0, 0), ^(size_t i){
515 img_ttf_apply_one(pt, i, ctf, action, wiener, d[i], res_lo, res_hi, psize, planf, planb);
516 });
517 #else
518 #pragma omp parallel for
519 for ( long i=0; i<pt->images(); i++ )
520 img_ttf_apply_one(pt, i, ctf, action, wiener, d[i], res_lo, res_hi, psize, planf, planb);
521 #endif
522
523 fft_destroy_plan(planf);
524 fft_destroy_plan(planb);
525
526 p->assemble_tiles(pt);
527
528 delete pt;
529 delete[] d;
530
531 return 0;
532 }
533
554 Bimage* img_ctf_radial_average(Bimage* p, long n, CTFparam* em_ctf)
555 {
556 if ( em_ctf->check_defocus() || em_ctf->check_Cs() ) {
557 cerr << "in img_ctf_radial_average" << endl;
558 // return NULL;
559 if ( em_ctf->defocus_average() <= 1 ||
560 em_ctf->defocus_average() >= 2e5 )
561 em_ctf->defocus_average(2e4);
562 if ( em_ctf->Cs() < 1e3 || em_ctf->Cs() > 1e8 )
563 em_ctf->Cs(2e7);
564 }
565
566 unsigned long nrad = p->sizeX()/2;
567 Bimage* prad = new Bimage(Double, TSimple, nrad, 1, 1, 1);
568 prad->sampling(p->sampling().x(), 1, 1);
569
570 long i, x, y, z;
571 long iradius;
572 double dx, dy, dz, radius, angle, fraction, cosang, sinang;
573 double smin2 = 1-em_ctf->defocus_deviation()/em_ctf->defocus_average();
574 double smax2 = 1+em_ctf->defocus_deviation()/em_ctf->defocus_average();
575 double* num = new double[nrad];
576 double* rdata = (double *) prad->data_pointer();
577
578 if ( verbose & VERB_FULL ) {
579 cout << "Radial average for CTF fitting:" << endl;
580 cout << "Size: " << nrad << endl;
581 cout << "Power spectrum origin: " << p->image->origin() << endl;
582 cout << "Defocus, deviation, angle: " <<
583 em_ctf->defocus_average() << " " << em_ctf->defocus_deviation() << " " << em_ctf->astigmatism_angle() << endl;
584 }
585
586 if ( p->sizeZ() < 2 ) {
587 if ( verbose & VERB_DEBUG )
588 cout << "DEBUG img_ctf_radial_average: doing image " << n+1 << endl;
589 for ( i=0; i<nrad; i++ ) num[i] = 0;
590 for ( y=0; y<p->sizeY(); y++ ) {
591 dy = y - p->image[n].origin().y();
592 for ( x=0; x<p->sizeX(); x++ ) {
593 dx = x - p->image[n].origin().x();
594 radius = sqrt(dx*dx + dy*dy);
595 iradius = (long) radius;
596 if ( iradius < nrad ) {
597 angle = atan2(dy, dx) - em_ctf->astigmatism_angle();
598 cosang = cos(angle);
599 sinang = sin(angle);
600 radius *= sqrt(smax2*cosang*cosang + smin2*sinang*sinang);
601 if ( !isfinite(radius) )
602 cerr << "Warning: radius for " << iradius << " not finite!" << endl;
603 iradius = (long) radius;
604 if ( iradius < nrad - 1 ) {
605 fraction = radius - iradius;
606 num[iradius] += 1.0 - fraction;
607 i = p->index(0,x,y,0,n);
608 rdata[iradius] += (1.0 - fraction)*(*p)[i];
609 iradius++;
610 if ( iradius < nrad ) {
611 num[iradius] += fraction;
612 rdata[iradius] += fraction*(*p)[i];
613 }
614 }
615 }
616 }
617 }
618 for ( iradius=0; iradius<nrad; iradius++ )
619 if ( num[iradius] ) rdata[iradius] /= num[iradius];
620 } else {
621 if ( verbose & VERB_DEBUG )
622 cout << "DEBUG img_ctf_radial_average: calculating 3D RPS" << endl;
623 for ( i=0; i<nrad; i++ ) num[i] = 0;
624 for ( z=0; z<p->sizeZ(); z++ ) {
625 dz = z - p->image[n].origin().z();
626 for ( y=0; y<p->sizeY(); y++ ) {
627 dy = y - p->image[n].origin().y();
628 for ( x=0; x<p->sizeX(); x++ ) {
629 dx = x - p->image[n].origin().x();
630 radius = sqrt(dx*dx + dy*dy + dz*dz);
631 iradius = (long) radius;
632 if ( iradius < nrad - 1 ) {
633 fraction = radius - iradius;
634 num[iradius] += 1.0 - fraction;
635 i = p->index(0,x,y,z,n);
636 rdata[n*nrad+iradius] += (1.0 - fraction)*(*p)[i];
637 iradius++;
638 if ( iradius < nrad ) {
639 num[iradius] += fraction;
640 rdata[iradius] += fraction*(*p)[i];
641 }
642 }
643 }
644 }
645 }
646 for ( iradius=0; iradius<nrad; iradius++ )
647 if ( num[iradius] ) rdata[iradius] /= num[iradius];
648 }
649
650 delete[] num;
651
652 prad->statistics();
653
654 return prad;
655 }
656
657
658 //Expects a radial average
659 Bimage* img_ctf_radial_subtract_baseline(Bimage* prad, double real_size, CTFparam* em_ctf)
660 {
661 long i;
662 double s, recip_interval = 1.0/real_size;
663 Bimage* prmb = prad->copy();
664
665 for ( i=0; i<prmb->sizeX(); i++ ) {
666 s = i*recip_interval;
667 prmb->set(i, (*prmb)[i] - em_ctf->calc_baseline(s));
668 }
669
670 return prmb;
671 }
672
705 double img_ctf_fit(Bimage* p, long n, CTFparam* em_ctf, double lores, double hires)
706 {
707 if ( hires < 2*p->sampling().x() ) hires = 2*p->sampling().x();
708 if ( lores < hires ) lores = p->real_size().x();
709 if ( lores > p->real_size().x() ) lores = p->real_size().x();
710
711 if ( verbose & VERB_PROCESS ) {
712 cout << "Determining CTF parameters:" << endl;
713 cout << "Sampling: " << p->sampling().x() << " A" << endl;
714 cout << "Voltage: " << em_ctf->volt() << " V" << endl;
715 cout << "Wavelength: " << em_ctf->lambda() << " A" << endl;
716 cout << "Cs: " << em_ctf->Cs() << " A" << endl;
717 cout << "Amplitude contrast: " << em_ctf->amp_fac() << endl;
718 cout << "Resolution range: " << hires << " - " << lores << " A" << endl;
719 cout << "Baseline type: " << em_ctf->baseline_type() << endl;
720 cout << "Envelope type: " << em_ctf->envelope_type() << endl << endl;
721 }
722
723 if ( em_ctf->defocus_average() < 1 ) {
724 em_ctf->defocus_average(1000);
725 em_ctf->defocus_deviation(0);
726 }
727
728 long i(0), iter(10);
729 double fom(0), fom_prev(-1), fom_max(0);
730 CTFparam* best_ctf = em_ctf->copy();
731
732 // img_ctf_fit_astigmatism_new(p, em_ctf, lores, hires);
733
734 fom = fom_max = img_ctf_find_defocus(p, n, em_ctf, lores, hires);
735 best_ctf->update(em_ctf);
736
737 while ( ( fom_max > fom_prev ) && --iter ) {
738
739 fom_prev = fom;
740
741 img_ctf_fit_baseline(p, n, em_ctf, lores, hires);
742
743 img_ctf_fit_envelope(p, n, em_ctf, lores, hires);
744
745 fom = img_ctf_find_defocus(p, n, em_ctf, lores, hires,
746 em_ctf->defocus_average()/1.2, em_ctf->defocus_average()*1.2,
747 em_ctf->defocus_average()*0.2);
748
749 img_ctf_fit_astigmatism(p, n, em_ctf, lores, hires);
750
751 if ( i<1 || fom_max <= fom ) {
752 fom_max = fom;
753 best_ctf->update(em_ctf);
754 }
755
756 i++;
757
758 if ( verbose )
759 cout << "Best defocus (" << i << "): "
760 << best_ctf->defocus_average()
761 << " +- " << best_ctf->defocus_deviation()
762 << " @ " << best_ctf->astigmatism_angle()*180/M_PI
763 << " (" << fom_max << ")" << endl;
764
765 }
766
767 em_ctf->update(best_ctf);
768
769 return em_ctf->zero(1);
770 }
771
772 /*
773 Expects a radial power spectrum
774 Measures the astigmatism between the resolution limits
775 The variable real_size is the box x-size in angstrom
776 Zeroes are calculated, given in spatial frequency units
777 For every two successive zeroes between the resolution limits:
778 the minimum within a kernel is found at each zero: [ib1]:b1 and [ib2]:b2
779 the maximum halfway between the zeroes within a kernel is found: [im]:m
780 Measure: sum(im*(m - (b1+b2)/2))
781 the intent is that this measure should be maximum for the correct astigmatism parameters
782 */
783 double img_ctf_astigmatism_measure(Bimage* p, long n, double real_size, CTFparam* em_ctf, double lores, double hires)
784 {
785 Bimage* prad = img_ctf_radial_average(p, n, em_ctf);
786
787 if ( !prad ) {
788 cerr << "Error in img_ctf_fit_astigmatism: No radial power spectrum calculated!" << endl;
789 return -1;
790 }
791
792 double pixel_size = prad->sampling().x();
793 if ( pixel_size <= 0 ) pixel_size = 1;
794
795 long i, ib1, ib2, im, j, nn(0), nz(0);
796 long k = prad->sizeX()/100;
797 if ( k < 2 ) k = 2;
798 long ilo = (long) (real_size/lores + 0.5);
799 long ihi = (long) (real_size/hires + 0.5);
800 if ( ihi >= prad->sizeX() ) ihi = prad->sizeX() - 1;
801 double b1, b2, m, OM(0);
802 double max_s = 0.45/pixel_size;
803
804 Bimage* prmb = img_ctf_radial_subtract_baseline(prad, real_size, em_ctf);
805
806 double* zero = em_ctf->zeroes(max_s, nz);
807
808 if ( nz > prad->sizeX() ) nz = prad->sizeX();
809
810 for ( i=1; i<nz; i++ ) {
811 ib1 = (long) (zero[i-1]*real_size + 0.5);
812 ib2 = (long) (zero[i]*real_size + 0.5);
813 im = (ib1 + ib2)/2;
814 if ( im >= ilo && im <= ihi ) {
815 for ( b1=(*prmb)[ib1], j=ib1-k; j<=ib1+k; j++ )
816 if ( b1 > (*prmb)[j] ) b1 = (*prmb)[j];
817 for ( b2=(*prmb)[ib2], j=ib2-k; j<=ib2+k; j++ )
818 if ( b2 > (*prmb)[j] ) b2 = (*prmb)[j];
819 for ( m=(*prmb)[im], j=im-k; j<=im+k; j++ )
820 if ( m < (*prmb)[j] ) m = (*prmb)[j];
821 OM += im*(m - (b1 + b2)/2);
822 nn += im;
823 }
824 }
825
826 OM /= nn;
827
828 delete prad;
829 delete prmb;
830 delete[] zero;
831
832 if ( verbose & VERB_FULL )
833 cout << "Fitting measure: " << OM << endl;
834
835 return OM;
836 }
837
852 double img_ctf_fit_baseline(Bimage* p, long n, CTFparam* em_ctf, double lores, double hires)
853 {
854 Bimage* prad = img_ctf_radial_average(p, n, em_ctf);
855
856 if ( !prad ) {
857 cerr << "Error in img_ctf_fit_baseline: No radial power spectrum calculated!" << endl;
858 return -1;
859 }
860
861 double R = ctf_fit_baseline(prad, p->real_size().x(), em_ctf, lores, hires);
862
863 delete prad;
864
865 if ( verbose & VERB_PROCESS )
866 em_ctf->show_baseline();
867
868 return R;
869 }
870
885 double img_ctf_fit_envelope(Bimage* p, long n, CTFparam* em_ctf, double lores, double hires)
886 {
887 Bimage* prad = img_ctf_radial_average(p, n, em_ctf);
888
889 if ( !prad ) {
890 cerr << "Error in img_ctf_fit_envelope: No radial power spectrum calculated!" << endl;
891 return -1;
892 }
893
894 double R = ctf_fit_envelope(prad, p->real_size().x(), em_ctf, lores, hires);
895
896 delete prad;
897
898 if ( verbose & VERB_PROCESS )
899 em_ctf->show_envelope();
900
901 return R;
902 }
903
904 double ctf_test_defocus(CTFparam* em_ctf, double def, long nx,
905 double step_size, double* r, long rmin, long rmax)
906 {
907 long i;
908 long nr(rmax-rmin+1);
909 double fom(0);
910 double* c;
911
912 em_ctf->defocus_average(def);
913
914 c = em_ctf->calculate(nx, 1, step_size);
915
916 for ( i=rmin; i<=rmax; i++ ) fom += (c[i]*c[i] - 0.5)*r[i];
917 fom /= nr;
918
919 delete[] c;
920
921 return fom;
922 }
923
942 double img_ctf_find_defocus(Bimage* p, long n, CTFparam* em_ctf,
943 double lores, double hires,
944 double def_start, double def_end, double def_inc)
945 {
946 Bimage* prad = img_ctf_radial_average(p, n, em_ctf);
947
948 if ( hires < 2*p->sampling().x() ) hires = 2*p->sampling().x();
949 if ( lores < hires ) lores = 100;
950 if ( lores > 100 ) lores = 100;
951
952 long i, nx(p->sizeX()/2);
953 double step_size = 1/p->real_size().x();
954 long rmin = (long) (p->real_size().x()/lores);
955 long rmax = (long) (p->real_size().x()/hires);
956
957 for ( i=0; i<rmin; i++ ) prad->set(i, (*prad)[rmin]);
958
959 double* r = moving_polynomial(2, nx, (double *) prad->data_pointer(), nx/5);
960
961 for ( i=0; i<nx; i++ )
962 if ( r[i] ) r[i] = (*prad)[i]/r[i] - 1;
963 else r[i] = 0;
964
965 long nr(rmax-rmin+1);
966 double def, def_best(0);
967 double fom, fom_max(0);
968
969 if ( verbose & VERB_PROCESS ) {
970 cout << "Defocus range: " << def_start*1e-4 << " - " << def_end*1e-4 << endl;
971 cout << "Accelerating voltage: " << em_ctf->volt()*1e-3 << " kV" << endl;
972 cout << "Wavelength: " << em_ctf->lambda() << " A" << endl;
973 cout << "Spherical abberation: " << em_ctf->Cs()*1e-7 << " mm" << endl;
974 cout << "Amplitude contrast: " << em_ctf->amp_fac() << endl;
975 cout << "Range: " << rmin << " - " << rmax << endl;
976 cout << "Frequency step size: " << step_size << " 1/A" << endl;
977 }
978
979 if ( verbose & VERB_FULL )
980 cout << "Defocus\tCC" << endl;
981 while ( def_inc >= 50 ) {
982 for ( def=def_start; def<=def_end; def+=def_inc ) {
983 fom = ctf_test_defocus(em_ctf, def, nx, step_size, r, rmin, rmax);
984 if ( fom_max < fom ) {
985 fom_max = fom;
986 def_best = def;
987 }
988 if ( verbose & VERB_FULL )
989 cout << def*1e-4 << tab << fom << endl;
990 }
991 def_start = def_best - 2*def_inc;
992 def_end = def_best + 2*def_inc;
993 def_inc /= 1.6;
994 if ( def_start < 100 ) def_start = 100;
995 // cout << "def_start=" << def_start << endl;
996 }
997
998 delete[] r;
999 delete prad;
1000
1001 em_ctf->defocus_average(def_best);
1002 em_ctf->fom(fom_max);
1003
1004 return fom_max;
1005 }
1006
1024 double img_ctf_fit_astigmatism(Bimage* p, long n, CTFparam* em_ctf, double lores, double hires)
1025 {
1026 long i, j, na;
1027 double real_size = p->real_size().x();
1028 double angle, angle_min = -M_PI_2, angle_max = M_PI_2, angle_range = M_PI, angle_inc = M_PI/9;
1029 double def_dev = 100, ddiff, prev_fom(0), best_dev = em_ctf->defocus_deviation(), best_ang = em_ctf->astigmatism_angle();
1030 if ( em_ctf->defocus_deviation() > 0 ) def_dev = em_ctf->defocus_deviation(); // Use the input deviation
1031 double* fom;
1032 CTFparam* ec;
1033
1034 double best_fom = img_ctf_astigmatism_measure(p, n, real_size, em_ctf, lores, hires);
1035
1036 if ( verbose & VERB_FULL )
1037 cout << "Starting astigmatism: " << em_ctf->defocus_average() << " "
1038 << em_ctf->defocus_deviation() << " " << em_ctf->astigmatism_angle() << " " << best_fom << endl;
1039
1040 for ( i=0; i<20 && ( best_fom/prev_fom - 1 > 1e-6 ); i++ ) {
1041 for ( na=0, angle=angle_min; angle<=angle_max; angle+=angle_inc ) na++;
1042 ec = new CTFparam[na];
1043 fom = new double[na];
1044 em_ctf->defocus_deviation(def_dev);
1045 for ( angle=angle_min, j=0; angle<=angle_max; angle+=angle_inc, j++ ) {
1046 ec[j] = *em_ctf;
1047 ec[j].astigmatism_angle(angle);
1048 }
1049
1050 #ifdef HAVE_GCD
1051 dispatch_apply(na, dispatch_get_global_queue(0, 0), ^(size_t k){
1052 fom[k] = img_ctf_astigmatism_measure(p, n, real_size, &ec[k], lores, hires);
1053 });
1054 #else
1055 #pragma omp parallel for
1056 for ( j=0; j<na; j++ ) {
1057 fom[j] = img_ctf_astigmatism_measure(p, n, real_size, &ec[j], lores, hires);
1058 }
1059 #endif
1060
1061 for ( j=0; j<na; j++ ) {
1062 if ( best_fom < fom[j] ) {
1063 prev_fom = best_fom;
1064 best_fom = fom[j];
1065 best_dev = def_dev;
1066 best_ang = ec[j].astigmatism_angle();
1067 }
1068 if ( verbose & VERB_FULL )
1069 cout << em_ctf->defocus_average() << tab << def_dev << tab << ec[j].astigmatism_angle() << tab << fom[j] << tab <<
1070 em_ctf->defocus_average() << tab << best_dev << tab << best_ang << tab << best_fom << endl;
1071 }
1072 ddiff = best_dev - def_dev;
1073
1074 delete[] ec;
1075 delete[] fom;
1076
1077 if ( ddiff == 0 ) {
1078 def_dev += 100;
1079 angle_range /= 2;
1080 angle_min = best_ang - angle_range/2;
1081 angle_max = best_ang + angle_range/2;
1082 angle_inc /= 2;
1083 } else def_dev += ddiff/2;
1084 }
1085
1086 if ( best_ang < -M_PI_2 ) best_ang += M_PI;
1087 if ( best_ang > M_PI_2 ) best_ang -= M_PI;
1088
1089 em_ctf->defocus_deviation(best_dev);
1090 em_ctf->astigmatism_angle(best_ang);
1091
1092 if ( verbose & VERB_PROCESS )
1093 cout << "Astigmatism refined: " << em_ctf->defocus_average() << " +- "
1094 << em_ctf->defocus_deviation() << " @ " << em_ctf->astigmatism_angle()*180.0/M_PI << " (OM = " << best_fom << ")" << endl << endl;
1095
1096 return best_fom;
1097 }
1098
1099 double img_ctf_fit_astigmatism_new(Bimage* p, CTFparam* em_ctf, double lores, double hires)
1100 {
1101 if ( hires < 2*p->sampling().x() ) hires = 2*p->sampling().x();
1102 if ( lores < hires ) lores = p->real_size().x();
1103 if ( lores > p->real_size().x() ) lores = p->real_size().x();
1104
1105 size_t i, n, j;
1106 size_t rmin = (size_t) (p->real_size().x()/lores);
1107 size_t rmax = (size_t) (p->real_size().x()/hires);
1108
1109 double ell, ell_start(0.001), ell_mult(1.2), ell_max(0.1), ell_end(ell_max);
1110 double best_ell(0), best_angle(0);
1111 double angle, ang_start(0), ang_inc(M_PI/36), ang_end(M_PI);
1112 double best_fom(0), mell, mang, m, d;
1113 double *ar, *fom;
1114
1115 Bimage* prad = p->radial(rmin, rmax, 1, 1);
1116 long nr = prad->sizeX();
1117 double* ra = new double[nr];
1118 for ( j=0; j<nr; j++ ) ra[j] = (*prad)[j];
1119 double* r = moving_polynomial(2, nr, ra, nr/5);
1120 delete prad;
1121 delete[] ra;
1122
1123 // Bimage* pell = img_elliptical_average(p, rmin, rmax, best_ell, best_angle);
1124 Bimage* pell = p->radial(rmin, rmax, 1, best_ell, best_angle, NULL);
1125 for ( best_fom = 0, j=rmin; j<=rmax; j++ ) {
1126 d = (*pell)[j] / r[j] - 1;
1127 best_fom += d*d;
1128 }
1129 best_fom = sqrt(best_fom/(rmax - rmin + 1));
1130 // best_fom = pell->standard_deviation();
1131 delete pell;
1132
1133 if ( verbose & VERB_FULL ) {
1134 cout << setprecision(4) << "Ell\tAng\tFOM" << endl;
1135 cout << best_ell << tab << best_angle*180.0/M_PI << tab << best_fom << endl;
1136 }
1137
1138 while ( ell_mult > 1.001 ) {
1139 for ( ell=ell_start; ell<ell_end; ell*=ell_mult ) {
1140 mell = mang = m = 0;
1141 for ( n=0, angle=ang_start; angle<ang_end; angle+=ang_inc ) n++;
1142 ar = new double[n];
1143 fom = new double[n];
1144 for ( i=0, angle=ang_start; angle<ang_end; angle+=ang_inc, i++ ) ar[i] = angle;
1145
1146 #ifdef HAVE_GCD
1147 dispatch_apply(n, dispatch_get_global_queue(0, 0), ^(size_t k){
1148 Bimage* pel = p->radial(rmin, rmax, 1, ell, ar[k], NULL);
1149 double d;
1150 fom[k] = 0;
1151 for ( long j=rmin; j<=rmax; j++ ) {
1152 d = (*pel)[j] / r[j] - 1;
1153 fom[k] += d*d;
1154 }
1155 fom[k] = sqrt(fom[k]/(rmax - rmin + 1));
1156 // fom[k] = pell->standard_deviation();
1157 delete pel;
1158 });
1159 #else
1160 #pragma omp parallel for
1161 for ( i=0; i<n; i++ ) {
1162 Bimage* pel = p->radial(rmin, rmax, 1, ell, ar[i], NULL);
1163 double d;
1164 fom[i] = 0;
1165 for ( long j=rmin; j<=rmax; j++ ) {
1166 d = (*pel)[j] / r[j] - 1;
1167 fom[i] += d*d;
1168 }
1169 fom[i] = sqrt(fom[i]/(rmax - rmin + 1));
1170 // fom[i] = pell->standard_deviation();
1171 delete pel;
1172 }
1173 #endif
1174
1175 for ( i=0; i<n; i++ ) {
1176 // cout << ell << tab << angle << tab << fom << endl;
1177 if ( m < fom[i] ) {
1178 m = fom[i];
1179 mell = ell;
1180 mang = ar[i];
1181 }
1182 if ( best_fom < fom[i] ) {
1183 best_fom = fom[i];
1184 best_ell = ell;
1185 best_angle = ar[i];
1186 }
1187 }
1188
1189 delete[] ar;
1190 delete[] fom;
1191
1192 if ( verbose & VERB_FULL )
1193 cout << mell << tab << mang*180.0/M_PI << tab << m << endl;
1194 }
1195 ell_start = best_ell/ell_mult;
1196 ell_end = best_ell*ell_mult;
1197 ell_mult = (ell_mult - 1)/2 + 1;
1198 ang_start = best_angle - 4*ang_inc;
1199 ang_end = best_angle + 4*ang_inc;
1200 ang_inc /= 2;
1201 }
1202
1203 if ( verbose )
1204 cout << "Astigmatism: " << best_ell << " "
1205 << best_angle*180.0/M_PI << " " << best_fom << endl;
1206
1207 em_ctf->defocus_deviation(best_ell*em_ctf->defocus_average());
1208 em_ctf->astigmatism_angle(best_angle);
1209
1210 return best_fom;
1211 }
1212
1213 double ctf_R(Bsimplex* simp)
1214 {
1215 long i, n(0);
1216 CTFparam* cp = new CTFparam;
1217
1218 cp->volt(simp->constant(0));
1219 cp->Cs(simp->constant(1));
1220 cp->amp_fac(simp->constant(2));
1221 cp->baseline_type((long) simp->constant(3));
1222 cp->defocus_average(simp->parameter(10));
1223 for ( i=0; i<5; i++ ) {
1224 cp->baseline(i, simp->parameter(i));
1225 cp->envelope(i, simp->parameter(i+5));
1226 }
1227
1228 double real_size = simp->constant(4);
1229 double lores = simp->constant(5);
1230 double hires = simp->constant(6);
1231
1232 long ilo = (long) (real_size/lores + 0.5);
1233 long ihi = (long) (real_size/hires + 0.5);
1234 if ( ihi >= simp->npoint ) ihi = simp->npoint - 1;
1235 double base, env, a, b, d, s, R(0);
1236 double recip_interval = 1.0/real_size;
1237
1238 double* ctf = cp->calculate(simp->npoint, 1, recip_interval);
1239
1240 for ( i=ilo; i<=ihi; i++ ) {
1241 s = simp->x[i];
1242 base = cp->calc_baseline(s);
1243 env = cp->calc_envelope(s);
1244 a = env*ctf[i]*ctf[i];
1245 b = simp->fx[i] - base;
1246 if ( a > 1e-3 && fabs(b) > 1e-3 ) {
1247 d = a/b - 1;
1248 R += d*d;
1249 n++;
1250 }
1251 }
1252
1253 R = sqrt(R/n);
1254
1255 delete[] ctf;
1256 delete cp;
1257
1258 if ( verbose & VERB_FULL )
1259 cout << "Fitting residual: " << R << endl;
1260
1261 return R;
1262 }
1263
1264 double ctf_fit_baseline(Bimage* prad, double real_size, CTFparam* em_ctf, double lores, double hires)
1265 {
1266 double pixel_size = prad->sampling().x();
1267 if ( pixel_size <= 0 ) pixel_size = 1;
1268
1269 long i, j, ib, n, nc(4);
1270 long istart = (long) (real_size/lores);
1271 long iend = (long) (real_size/hires);
1272 if ( istart < 1 ) istart = 1;
1273 if ( iend >= prad->sizeX() ) iend = prad->sizeX() - 1;
1274 long w = (iend - istart)/10;
1275
1276 double recip_interval = 1.0/real_size;
1277 double max_s = 0.45/pixel_size;
1278 long k = prad->sizeX()/100;
1279 if ( k < 1 ) k = 1;
1280
1281 double R = 1e30, coeff[NCTFPARAM];
1282 for ( i=0; i<NCTFPARAM; i++ ) coeff[i] = em_ctf->baseline(i);
1283
1284 double* s = new double [prad->sizeX()];
1285 double* d = new double [prad->sizeX()];
1286 for ( i=0; i<prad->sizeX(); i++ ) s[i] = d[i] = 0;
1287
1288 double* zero = em_ctf->zeroes(max_s, n);
1289
1290 if ( n > prad->sizeX() ) n = prad->sizeX();
1291
1292 if ( verbose & VERB_DEBUG )
1293 cout << "DEBUG ctf_fit_baseline: zeroes=" << n << endl;
1294
1295 double min = 1e10;
1296 double* mavg = NULL;
1297
1298 if ( n > 3 ) { // Enough zeroes to fit the baseline
1299 for ( i=0; i<n; i++ ) {
1300 ib = (long) (zero[i]*real_size + 0.5);
1301 s[i] = zero[i];
1302 d[i]=(*prad)[ib];
1303 for ( j=(ib>k)?ib-k:0; j<=ib+k && j<prad->sizeX(); j++ ) // minimum within kernel
1304 if ( d[i] > (*prad)[j] ) d[i] = (*prad)[j];
1305 }
1306 } else { // Too few zeroes, use local minima
1307 mavg = moving_average(prad->sizeX(), (double *) prad->data_pointer(), prad->sizeX()/10);
1308 for ( i=istart, n=0; i<iend; i++ ) {
1309 if ( min > (*prad)[i] - mavg[i] ) {
1310 min = (*prad)[i] - mavg[i];
1311 s[n] = recip_interval*i;
1312 d[n] = (*prad)[i];
1313 if ( d[n] > mavg[i] ) d[n] = mavg[i];
1314 }
1315 if ( i%w == 0 ) {
1316 min = 1e10;
1317 n++;
1318 }
1319 }
1320 s[n] = 10;
1321 d[n] = 0;
1322 n++;
1323 delete[] mavg;
1324 }
1325
1326 if ( verbose & VERB_DEBUG )
1327 cout << "DEBUG ctf_fit_baseline: fitting baseline type " << em_ctf->baseline_type() << endl;
1328
1329 switch ( em_ctf->baseline_type() ) {
1330 case 1:
1331 if ( n < 5 ) nc = n - 1;
1332 R = fit_polynomial(n, s, d, nc, coeff);
1333 break;
1334 case 2:
1335 R = ctf_fit_double_gaussian_baseline(n, s, d, coeff);
1336 break;
1337 case 3:
1338 R = ctf_fit_eman_to_baseline(n, s, d, coeff);
1339 break;
1340 default:
1341 cerr << "Error: Baseline type " << em_ctf->baseline_type() << " not supported" << endl;
1342 }
1343
1344 if ( em_ctf->baseline_type() > 0 && em_ctf->baseline_type() < 4 )
1345 em_ctf->baseline(coeff);
1346
1347 delete[] s;
1348 delete[] d;
1349 delete[] zero;
1350
1351 return R;
1352 }
1353
1354 double ctf_fit_envelope(Bimage* prad, double real_size, CTFparam* em_ctf, double lores, double hires)
1355 {
1356 double pixel_size = prad->sampling().x();
1357 if ( pixel_size <= 0 ) pixel_size = 1;
1358
1359 long i, j, nzero, ib;
1360 long k = prad->sizeX()/80;
1361 if ( k < 1 ) k = 1;
1362
1363 double max_s = 0.45/pixel_size;
1364 double R = 1e30;
1365
1366 double* zero = em_ctf->zeroes(max_s, nzero);
1367
1368 if ( nzero > prad->sizeX() ) nzero = prad->sizeX();
1369
1370 double b, si, coeff[NCTFPARAM];
1371 double* s = new double[nzero];
1372 double* d = new double[nzero];
1373 for ( i=0; i<NCTFPARAM; i++ ) coeff[i] = 0;
1374 for ( i=0; i<nzero; i++ ) s[i] = d[i] = 0;
1375
1376 ib = (long) (zero[0]*real_size + 0.5);
1377 d[0] = 0;
1378 for ( i=ib/2; i<ib; i++ ) {
1379 si = i/real_size;
1380 b = (*prad)[i] - em_ctf->calc_baseline(si);
1381 if ( d[0] < b ) {
1382 d[0] = b;
1383 s[0] = si;
1384 }
1385 }
1386
1387 for ( i=1; i<nzero; i++ ) {
1388 s[i] = (zero[i-1]+zero[i])*0.5;
1389 ib = (long) (s[i]*real_size + 0.5);
1390 b = em_ctf->calc_baseline(s[i]);
1391 d[i] = (*prad)[ib] - b;
1392 for ( j=(ib>k)?ib-k:0; j<=ib+k && j<prad->sizeX(); j++ ) // maximum within kernel
1393 if ( d[i] < (*prad)[j] - b ) d[i] = (*prad)[j] - b;
1394 }
1395
1396 if ( verbose & VERB_DEBUG ) {
1397 cout << "DEBUG ctf_fit_envelope: type " << em_ctf->envelope_type() << endl;
1398 for ( i=0; i<5; i++ ) cout << tab << em_ctf->envelope(i);
1399 cout << endl;
1400 }
1401
1402 switch ( em_ctf->envelope_type() ) {
1403 case 1: // Single gaussian
1404 for ( i=0; i<2; i++ ) coeff[i+1] = em_ctf->envelope(i);
1405 R = ctf_fit_gaussian(nzero-1, s, d, coeff);
1406 for ( i=0; i<2; i++ ) coeff[i] = coeff[i+1];
1407 coeff[i] = 0;
1408 break;
1409 case 2: // Single gaussian with constant
1410 for ( i=0; i<3; i++ ) coeff[i] = em_ctf->envelope(i);
1411 R = ctf_fit_gaussian(nzero-1, s, d, coeff);
1412 break;
1413 case 3: // Double gaussian
1414 for ( i=0; i<4; i++ ) coeff[i+1] = em_ctf->envelope(i);
1415 R = ctf_fit_double_gaussian_envelope(nzero, s, d, coeff);
1416 for ( i=0; i<4; i++ ) coeff[i] = coeff[i+1];
1417 coeff[i] = 0;
1418 break;
1419 case 4: // Double gaussian with constant
1420 for ( i=0; i<5; i++ ) coeff[i] = em_ctf->envelope(i);
1421 R = ctf_fit_double_gaussian_envelope(nzero, s, d, coeff);
1422 break;
1423 default: break;
1424 }
1425
1426 if ( verbose & VERB_DEBUG ) {
1427 cout << "DEBUG ctf_fit_envelope:";
1428 for ( i=0; i<5; i++ ) cout << tab << coeff[i];
1429 cout << endl;
1430 }
1431
1432 em_ctf->envelope(coeff);
1433
1434 delete[] zero;
1435 delete[] s;
1436 delete[] d;
1437
1438 return R;
1439 }
1440
1441 /*
1442 @brief Fits an EMAN-style baseline function.
1443 @param n number of data points.
1444 @param *x x array (at least order+1 values).
1445 @param *y y array (at least order+1 values).
1446 @param *coeff array in which 4 coefficients are returned
1447 (if NULL, no coefficients returned).
1448 @return double R value.
1449
1450 EMAN baseline function:
1451 y = a + b*exp( c*sqrt(s) + d*s^2 )
1452 **/
1453 double ctf_fit_eman_to_baseline(long n, double* x, double* y, double* coeff)
1454 {
1455 long i;
1456
1457 Bsimplex simp(1, 4, 0, n, x, y);
1458
1459 simp.parameters(4, coeff);
1460 simp.limits(0, 0, 1000);
1461 simp.limits(1, 0, 1000);
1462 simp.limits(2, -100, 100);
1463 simp.limits(3, -100, 0);
1464
1465 double R = simp.run(10000, 0.001, eman_baseline_R);
1466
1467 for ( i=0; i<4; i++ ) coeff[i] = simp.parameter(i);
1468
1469 return R;
1470 }
1471
1472 double eman_baseline_R(Bsimplex* simp)
1473 {
1474 long i;
1475 double R(0), df;
1476
1477 for ( i=0; i<simp->npoint; i++ ) {
1478 df = simp->fx[i] - (simp->param[0] + simp->param[1]*
1479 exp(simp->param[2]*sqrt(simp->x[i]) + simp->param[3]*simp->x[i]*simp->x[i]));
1480 R += df*df;
1481 }
1482
1483 R = sqrt(R/i);
1484
1485 return R;
1486 }
1487
1488
1489 /*
1490 @brief Fits a gaussian function.
1491 @param n number of data points.
1492 @param *x x array (at least order+1 values).
1493 @param *y y array (at least order+1 values).
1494 @param *coeff array in which 3 coefficients are returned
1495 (if NULL, no coefficients returned).
1496 @return double R value.
1497
1498 Gaussian function:
1499 y = a + b*exp(c*s^2)
1500 **/
1501 double ctf_fit_gaussian(long n, double* x, double* y, double* coeff)
1502 {
1503 long i;
1504
1505 Bsimplex simp(1, 3, 0, n, x, y);
1506
1507 simp.parameters(3, coeff);
1508 if ( coeff[0] ) simp.limits(0, 0, 1000);
1509 simp.limits(1, 0.001, 100);
1510 simp.limits(2, -1e4, -0.1);
1511
1512 double R = simp.run(10000, 0.01, gaussian_R);
1513
1514 for ( i=0; i<3; i++ ) coeff[i] = simp.parameter(i);
1515
1516 return R;
1517 }
1518
1519 double gaussian_R(Bsimplex* simp)
1520 {
1521 long i;
1522 double R(0), df, s2;
1523
1524 for ( i=0; i<simp->npoint; i++ ) {
1525 s2 = simp->x[i]*simp->x[i];
1526 df = simp->fx[i] - (simp->param[0] + simp->param[1]*exp(simp->param[2]*s2));
1527 R += df*df;
1528 }
1529
1530 R = sqrt(R/i);
1531
1532 return R;
1533 }
1534
1535 /*
1536 @brief Fits a double gaussian function.
1537 @param n number of data points.
1538 @param *x x array (at least order+1 values).
1539 @param *y y array (at least order+1 values).
1540 @param *coeff array in which 5 coefficients are returned
1541 (if NULL, no coefficients returned).
1542 @return double R value.
1543
1544 Double gaussian function:
1545 y = a + b*exp(c*s^2) + d*exp(f*s^2)
1546 **/
1547 double ctf_fit_double_gaussian_baseline(long n, double* x, double* y, double* coeff)
1548 {
1549 long i;
1550
1551 Bsimplex simp(1, 5, 0, n, x, y);
1552
1553 simp.parameters(5, coeff);
1554 simp.limits(0, 0, 1000);
1555 simp.limits(1, 0, 100);
1556 simp.limits(2, -1000, -0.1);
1557
1558 if ( n > 5 ) {
1559 simp.limits(3, 0, 1000);
1560 simp.limits(4, -10000, -1);
1561 }
1562
1563 double R = simp.run(10000, 0.01, double_gaussian_R);
1564
1565 for ( i=0; i<5; i++ ) coeff[i] = simp.parameter(i);
1566
1567 return R;
1568 }
1569
1570 /*
1571 @brief Fits a double gaussian function.
1572 @param n number of data points.
1573 @param *x x array (at least order+1 values).
1574 @param *y y array (at least order+1 values).
1575 @param *coeff array in which 5 coefficients are returned
1576 (if NULL, no coefficients returned).
1577 @return double R value.
1578
1579 Double gaussian function:
1580 y = a + b*exp(c*s^2) + d*exp(f*s^2)
1581 with a = 0
1582 **/
1583 double ctf_fit_double_gaussian_envelope(long n, double* x, double* y, double* coeff)
1584 {
1585 long i;
1586
1587 Bsimplex simp(1, 5, 0, n, x, y);
1588
1589 simp.parameters(5, coeff);
1590 if ( coeff[0] ) simp.limits(0, 0, 1000);
1591 simp.limits(1, 0.001, 100);
1592 simp.limits(2, -500, -0.1);
1593
1594 if ( n > 5 ) {
1595 simp.limits(3, 0.01, 100);
1596 simp.limits(4, -5000, -1);
1597 }
1598
1599 double R = simp.run(10000, 0.01, double_gaussian_R);
1600
1601 for ( i=0; i<5; i++ ) coeff[i] = simp.parameter(i);
1602
1603 return R;
1604 }
1605
1606 double double_gaussian_R(Bsimplex* simp)
1607 {
1608 long i;
1609 double R(0), df, s2;
1610
1611 for ( i=0; i<simp->npoint; i++ ) {
1612 s2 = simp->x[i]*simp->x[i];
1613 df = simp->fx[i] - (simp->param[0] + simp->param[1]*exp(simp->param[2]*s2) +
1614 simp->param[3]*exp(simp->param[4]*s2));
1615 R += df*df;
1616 }
1617
1618 R = sqrt(R/i);
1619
1620 return R;
1621 }
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1544
fft_setup_plan
fft_plan fft_setup_plan(size_t x, size_t y, size_t z, fft_direction dir, int opt)
Sets up a plan for fast Fourier transforms.
Definition: fft.cpp:31
img_ctf_apply_to_proj
int img_ctf_apply_to_proj(Bimage *proj, CTFparam *em_ctf, double defocus, double res_lo, double res_hi, fft_plan planf_2D, fft_plan planb_2D)
Applies a CTF to a projection image.
Definition: img_ctf.cpp:379
CTFparam::envelope
double * envelope()
Definition: ctf.h:101
Bimage::sizeZ
void sizeZ(size_t nz)
Definition: Bimage.h:335
CTFparam::zero
double zero(int i)
Definition: ctf.h:187
M_PI_2
#define M_PI_2
Definition: utilities.h:56
CTFparam::Cs
double Cs()
Definition: ctf.h:76
Bimage::replace
int replace(Bimage *img)
Replaces the data with that from the given image.
Definition: Bimage.cpp:2532
CTFparam::baseline_type
long baseline_type()
Definition: ctf.h:93
img_ttf_apply
int img_ttf_apply(Bimage *p, CTFparam *ctf, int action, double wiener, Vector3< int > tile_size, double tilt, double axis, double res_lo, double res_hi)
Applies or corrects for the tilted contrast transfer function (TTF).
Definition: img_ctf.cpp:431
fit_polynomial
double fit_polynomial(int n, double *x, double *y, int order, double *coeff)
Fits a data set to a polynomial function.
Definition: matrix_linear.cpp:99
double_gaussian_R
double double_gaussian_R(Bsimplex *simp)
Definition: img_ctf.cpp:1606
CTFparam::baseline
double * baseline()
Definition: ctf.h:95
Bimage.h
Header file for image class.
Bsimplex::parameter
void parameter(int i, double p)
Definition: simplex.h:58
moving_average.h
Header file moving average calculations.
moving_average
double * moving_average(int number, double *x, int window)
Calculates a moving average over an array of data.
Definition: moving_average.cpp:28
Bimage::extract_tiles
Bimage * extract_tiles(size_t nn, size_t ntiles, Vector3< size_t > *coords, Vector3< size_t > tile_size)
Extracts a set of tiles at specified positions from an image into a new image.
Definition: Bimage_extract.cpp:325
img_ctf_radial_subtract_baseline
Bimage * img_ctf_radial_subtract_baseline(Bimage *prad, double real_size, CTFparam *em_ctf)
Definition: img_ctf.cpp:659
Bimage::calculate_background
int calculate_background(size_t nn)
Calculates the background for one sub-image.
Definition: Bimage_background.cpp:26
Bimage::fft
int fft()
Definition: Bimage.h:695
Vector3::z
Type z()
Definition: Vector3.h:139
utilities.h
Header file for general utilities.
img_ctf_fit
double img_ctf_fit(Bimage *p, long n, CTFparam *em_ctf, double lores, double hires)
Determines the CTF parameters from a power spectrum.
Definition: img_ctf.cpp:705
CTFparam::astigmatism_angle
double astigmatism_angle()
Definition: ctf.h:91
Bsimplex
Structure used in the downhill simplex method.
Definition: simplex.h:39
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:106
CTFparam::calc_envelope
double calc_envelope(double s)
Definition: ctf.h:158
img_ctf_fit_astigmatism
double img_ctf_fit_astigmatism(Bimage *p, long n, CTFparam *em_ctf, double lores, double hires)
Fits the astigmatism with a given defocus, baseline and envelope.
Definition: img_ctf.cpp:1024
CTFparam::update
int update(CTFparam *ctf)
Updates a CTF structure from another.
Definition: ctf.cpp:20
ctf_test_defocus
double ctf_test_defocus(CTFparam *em_ctf, double def, long nx, double step_size, double *r, long rmin, long rmax)
Definition: img_ctf.cpp:904
Bsimplex::run
double run(int maxcycles, double tolerance, double(funk)(Bsimplex *))
Definition: simplex.cpp:103
CTFparam::show_envelope
void show_envelope()
Definition: ctf.h:232
Matrix.h
Generalized matrix class.
Bimage::index
size_t index(size_t nx, size_t ny) const
Definition: Bimage.h:339
gaussian_R
double gaussian_R(Bsimplex *simp)
Definition: img_ctf.cpp:1519
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:101
img_ttf_apply_one
int img_ttf_apply_one(Bimage *p, long nn, CTFparam *ctf, int action, double wiener, double def, double res_lo, double res_hi, Vector3< long > psize, fft_plan planf, fft_plan planb)
Definition: img_ctf.cpp:337
Bimage::size
Vector3< size_t > size() const
Definition: Bimage.h:330
Bimage::statistics
size_t statistics()
Calculates the statistics for an image.
Definition: Bimage_stats.cpp:22
b
long b
Definition: jpegint.h:371
Bimage::radial
Bimage * radial(size_t minrad, size_t maxrad, double rad_step, int wrap=0)
Calculates the radial average of an image.
Definition: Bimage_polar.cpp:33
TSimple
Definition: Bimage.h:54
Float
Definition: utilities.h:151
Vector3::max
Type max()
Definition: Vector3.h:149
Bimage::assemble_tiles
int assemble_tiles(Bimage *pt)
Assembles overlapping tiles into this image.
Definition: Bimage_combine.cpp:368
Bimage
General image parameter class.
Definition: Bimage.h:155
CTFparam::amp_fac
double amp_fac()
Definition: ctf.h:84
Bimage::real_size
Vector3< double > real_size()
Definition: Bimage.h:440
CTFparam::check_defocus
bool check_defocus()
Definition: ctf.h:108
CTFparam::calc_baseline
double calc_baseline(double s)
Definition: ctf.h:139
img_ctf_fit_envelope
double img_ctf_fit_envelope(Bimage *p, long n, CTFparam *em_ctf, double lores, double hires)
Fits only the envelope for a given CTF.
Definition: img_ctf.cpp:885
M_PI
#define M_PI
Definition: utilities.h:53
CTFparam::check_Cs
bool check_Cs()
Definition: ctf.h:114
Double
Definition: utilities.h:152
img_ctf_apply
int img_ctf_apply(Bimage *p, CTFparam *em_ctf, int action, double wiener, double lores, double hires)
Applies or corrects for the contrast transfer function (CTF).
Definition: img_ctf.cpp:268
Bimage::complex
Complex< double > complex(size_t j)
Returns a complex value at the given index.
Definition: Bimage.cpp:885
Bimage::sampling
void sampling(double s)
Definition: Bimage.h:443
ctf_fit_eman_to_baseline
double ctf_fit_eman_to_baseline(long n, double *x, double *y, double *coeff)
Definition: img_ctf.cpp:1453
CTFparam::delta_phi
double delta_phi(double s2, double angle)
Definition: ctf.h:126
Bimage::image_size
size_t image_size()
Definition: Bimage.h:240
Bsimplex::npoint
int npoint
Definition: simplex.h:44
Bimage::resize
int resize(Vector3< int > nusize, Vector3< int > translate, int fill_type=0, double fill=0)
Resizes without interpolation or rescaling.
Definition: Bimage_resize.cpp:28
eman_baseline_R
double eman_baseline_R(Bsimplex *simp)
Definition: img_ctf.cpp:1472
img_wave_aberration
Bimage * img_wave_aberration(CTFparam cp, Vector3< int > size, Vector3< float > sampling)
Calculates a wave aberration function.
Definition: img_ctf.cpp:193
img_ctf_astigmatism_measure
double img_ctf_astigmatism_measure(Bimage *p, long n, double real_size, CTFparam *em_ctf, double lores, double hires)
Definition: img_ctf.cpp:783
CTFparam::defocus_deviation
double defocus_deviation()
Definition: ctf.h:89
CTFparam::calculate
double calculate(double s2, double angle)
Definition: ctf.h:130
CTFparam::lambda
double lambda()
Definition: ctf.h:120
CTFparam::show
void show()
Definition: ctf.h:201
CTFparam::envelope_equation
Bstring envelope_equation()
Generates an envelope equation string from 4 coefficients.
Definition: ctf.cpp:209
ctf_fit_envelope
double ctf_fit_envelope(Bimage *prad, double real_size, CTFparam *em_ctf, double lores, double hires)
Definition: img_ctf.cpp:1354
ctf.h
Header file for CTF (contrast transfer function) functions.
ctf_fit_gaussian
double ctf_fit_gaussian(long n, double *x, double *y, double *coeff)
Definition: img_ctf.cpp:1501
img_ctf_calculate
Bimage * img_ctf_calculate(CTFparam cp, int action, double wiener, Vector3< long > size, Vector3< double > sampling, double lores, double hires)
Calculates a CTF complex image.
Definition: img_ctf.cpp:55
CTFparam::envelope_type
long envelope_type()
Definition: ctf.h:99
NCTFPARAM
#define NCTFPARAM
Definition: ctf.h:14
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:135
Bimage::set
void set(size_t j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:977
Bimage::extract
Bimage * extract(size_t nn)
Extracts one sub-image into new image structure.
Definition: Bimage_extract.cpp:21
ctf_fit_baseline
double ctf_fit_baseline(Bimage *prad, double real_size, CTFparam *em_ctf, double lores, double hires)
Definition: img_ctf.cpp:1264
CTFparam::fom
double fom()
Definition: ctf.h:105
fftwnd_data
Definition: fftw.h:355
Bsimplex::parameters
void parameters(int n, double *p)
Definition: simplex.h:55
Bimage::complex_to_real
void complex_to_real()
The real part of a complex image is written to a simple image.
Definition: Bimage_complex.cpp:50
Bimage::images
size_t images()
Definition: Bimage.h:441
img_ctf.h
Header file for CTF (contrast transfer function) functions.
Bimage::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:234
ctf_R
double ctf_R(Bsimplex *simp)
Definition: img_ctf.cpp:1213
Vector3::x
Type x()
Definition: Vector3.h:137
simplex.h
Nelder and Mead downhill simplex method for generalized parameter fitting.
Bstring
Definition: Bstring.h:28
Bimage::copy
Bimage * copy()
Copies the header information and data of an image into a new image structure.
Definition: Bimage.cpp:2414
Bimage::sizeX
void sizeX(size_t nx)
Definition: Bimage.h:333
Bsimplex::constant
void constant(int i, double p)
Definition: simplex.h:67
CTFparam::volt
double volt()
Definition: ctf.h:74
matrix_linear.h
Header file for matrix functions.
img_ctf_find_defocus
double img_ctf_find_defocus(Bimage *p, long n, CTFparam *em_ctf, double lores, double hires, double def_start, double def_end, double def_inc)
Searches for the defocus based on correlation.
Definition: img_ctf.cpp:942
FFTW_BACKWARD
Definition: fftw.h:64
img_ctf_fit_astigmatism_new
double img_ctf_fit_astigmatism_new(Bimage *p, CTFparam *em_ctf, double lores, double hires)
Definition: img_ctf.cpp:1099
CTFparam::baseline_equation
Bstring baseline_equation()
Generates a baseline equation string from 4 to 10 coefficients.
Definition: ctf.cpp:177
Vector3
Vector class for 3-value vectors used in 3D space. The internal variables are an array of 3 numbers...
Definition: Quaternion.h:16
fft_destroy_plan
int fft_destroy_plan(fft_plan plan)
Deallocates a plan for fast Fourier transforms.
Definition: fft.cpp:97
Bimage::pad
int pad(size_t sz, int fill_type=0, double fill=0)
Pads an image to a new size with a given fill value.
Definition: Bimage_resize.cpp:344
Bimage::sizeY
void sizeY(size_t ny)
Definition: Bimage.h:334
Vector3::min
Type min()
Definition: Vector3.h:143
Bsimplex::limits
void limits(int i, double vlo, double vhi)
Definition: simplex.h:60
ctf_fit_double_gaussian_envelope
double ctf_fit_double_gaussian_envelope(long n, double *x, double *y, double *coeff)
Definition: img_ctf.cpp:1583
img_ctf_fit_baseline
double img_ctf_fit_baseline(Bimage *p, long n, CTFparam *em_ctf, double lores, double hires)
Fits only the baseline for a given CTF.
Definition: img_ctf.cpp:852
CTFparam::defocus_average
double defocus_average()
Definition: ctf.h:87
CTFparam::zeroes
double * zeroes(double max_s, long &nzero)
Calculates the zeroes of a CTF curve on the spatial frequency scale.
Definition: ctf.cpp:131
Bsimplex::param
double * param
Definition: simplex.h:45
CTFparam::show_baseline
void show_baseline()
Definition: ctf.h:213
Vector3::y
Type y()
Definition: Vector3.h:138
NoTransform
Definition: Bimage.h:37
findNextPowerOf
int findNextPowerOf(int startNumber, int powerOf)
Finds the next greatest number that is a power of a given number.
Definition: utilities.cpp:404
Vector3::volume
double volume()
Definition: Vector3.h:205
moving_polynomial
double * moving_polynomial(int order, int number, double *x, int window)
Calculates a moving polynomial fit over an array of data.
Definition: moving_average.cpp:122
FFTW_FORWARD
Definition: fftw.h:64
VERB_FULL
#define VERB_FULL
Definition: utilities.h:103
VERB_LABEL
#define VERB_LABEL
Definition: utilities.h:100
CTFparam::copy
CTFparam * copy()
Copies the CTF structure to a new one.
Definition: ctf.cpp:54
Bsimplex::x
double * x
Definition: simplex.h:49
Bimage::fourier_type
FourierType fourier_type()
Definition: Bimage.h:324
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
ctf_fit_double_gaussian_baseline
double ctf_fit_double_gaussian_baseline(long n, double *x, double *y, double *coeff)
Definition: img_ctf.cpp:1547
Bsimplex::fx
double * fx
Definition: simplex.h:50
Bimage::image
Bsub_image * image
Definition: Bimage.h:186
CTFparam
Definition: ctf.h:25
img_ctf_radial_average
Bimage * img_ctf_radial_average(Bimage *p, long n, CTFparam *em_ctf)
Calculates the power spectrum radial average corrected for astigmatism.
Definition: img_ctf.cpp:554
verbose
int verbose