EMAN2
ctf.cpp
Go to the documentation of this file.
1/*
2 * Author: Steven Ludtke, 04/10/2003 (sludtke@bcm.edu)
3 * Copyright (c) 2000-2006 Baylor College of Medicine
4 *
5 * This software is issued under a joint BSD/GNU license. You may use the
6 * source code in this file under either license. However, note that the
7 * complete EMAN2 and SPARX software packages have some GPL dependencies,
8 * so you are responsible for compliance with the licenses of these packages
9 * if you opt to use BSD licensing. The warranty disclaimer below holds
10 * in either instance.
11 *
12 * This complete copyright notice must be included in any revised version of the
13 * source code. Additional authorship citations may be added, but existing
14 * author citations must be preserved.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 * */
31
32#include "ctf.h"
33#include "emdata.h"
34#include "xydata.h"
35#include "emassert.h"
36
37using namespace EMAN;
38
39EMAN1Ctf::EMAN1Ctf()
40{
41 defocus = 0;
42 bfactor = 0;
43 amplitude = 0;
44 ampcont = 0;
45 noise1 = 0;
46 noise2 = 0;
47 noise3 = 0;
48 noise4 = 0;
49 voltage = 0;
50 cs = 0;
51 apix = 0;
52}
53
54
56{
57}
58
59
60int EMAN1Ctf::from_string(const string & ctf)
61{
62 Assert(ctf != "");
63 char type;
64 int pos;
65 int i = sscanf(ctf.c_str(), "%c%f %f %f %f %f %f %f %f %f %f %f%n",
66 &type,&defocus, &bfactor, &amplitude, &ampcont, &noise1,
67 &noise2, &noise3, &noise4, &voltage, &cs, &apix, &pos);
68 defocus*=-1.0; // different convention in EMAN2
69 ampcont*=100.0; // different convention in EMAN2
70 bfactor*=4.0; // again
71 if (pos==-1) {
72 const char *s=ctf.c_str();
73 throw InvalidValueException(s," Invalid CTF string");
74 }
75
76 return 0;
77}
78
79void EMAN1Ctf::from_dict(const Dict & dict)
80{
81 defocus = dict["defocus"];
82 bfactor = dict["bfactor"];
83 amplitude = dict["amplitude"];
84 ampcont = dict["ampcont"];
85 noise1 = dict["noise1"];
86 noise2 = dict["noise2"];
87 noise3 = dict["noise3"];
88 noise4 = dict["noise4"];
89 voltage = dict["voltage"];
90 cs = dict["cs"];
91 apix = dict["apix"];
92}
93
95{
96 Dict dict;
97 dict["defocus"] = defocus;
98 dict["bfactor"] = bfactor;
99 dict["amplitude"] = amplitude;
100 dict["ampcont"] = ampcont;
101 dict["noise1"] = noise1;
102 dict["noise2"] = noise2;
103 dict["noise3"] = noise3;
104 dict["noise4"] = noise4;
105 dict["voltage"] = voltage;
106 dict["cs"] = cs;
107 dict["apix"] = apix;
108
109 return dict;
110}
111
112void EMAN1Ctf::from_vector(const vector<float>& vctf)
113{
114 defocus = vctf[0];
115 bfactor = vctf[1];
116 amplitude = vctf[2];
117 ampcont = vctf[3];
118 noise1 = vctf[4];
119 noise2 = vctf[5];
120 noise3 = vctf[6];
121 noise4 = vctf[7];
122 voltage = vctf[8];
123 cs = vctf[9];
124 apix = vctf[10];
125}
126
127vector<float> EMAN1Ctf::to_vector() const
128{
129 vector<float> vctf;
130
131 vctf.push_back(defocus);
132 vctf.push_back(bfactor);
133 vctf.push_back(amplitude);
134 vctf.push_back(ampcont);
135 vctf.push_back(noise1);
136 vctf.push_back(noise2);
137 vctf.push_back(noise3);
138 vctf.push_back(noise4);
139 vctf.push_back(voltage);
140 vctf.push_back(cs);
141 vctf.push_back(apix);
142
143 return vctf;
144}
145
146
148{
149 char ctf[1024];
150 sprintf(ctf, "O%1.10g %1.10g %1.10g %1.10g %1.10g %1.10g %1.10g %1.10g %1.10g %1.10g %1.10g",
152 apix);
153
154 return string(ctf);
155}
156
157void EMAN1Ctf::copy_from(const Ctf * new_ctf)
158{
159 if (new_ctf) {
160 const EMAN1Ctf *c = static_cast<const EMAN1Ctf *>(new_ctf);
161 defocus = c->defocus;
162 bfactor = c->bfactor;
163 amplitude = c->amplitude;
164 ampcont = c->ampcont;
165 noise1 = c->noise1;
166 noise2 = c->noise2;
167 noise3 = c->noise3;
168 noise4 = c->noise4;
169 voltage = c->voltage;
170 cs = c->cs;
171 apix = c->apix;
172 }
173}
174
175
176vector < float >EMAN1Ctf::compute_1d(int size, float ds, CtfType type, XYData * sf)
177{
178 Assert(size > 0);
179
180 float tmp_f1 = sqrt((float) 2) * size / 2;
181 int np = (int) ceil(tmp_f1) + 2;
182 vector < float >r;
183
184 r.resize(np);
185
186// float ds = 1 / (apix * size * CTFOS);
187 float s = 0;
188 float g1 = calc_g1();
189 float g2 = calc_g2();
190 float amp1 = calc_amp1();
191
192 switch (type) {
193 case CTF_AMP:
194 for (int i = 0; i < np; i++) {
195 float gamma = calc_gamma(g1, g2, s);
196 r[i] = calc_ctf1(amp1, gamma, s);
197 s += ds;
198 }
199 break;
200
201 case CTF_ABS:
202 for (int i = 0; i < np; i++) {
203 float gamma = calc_gamma(g1, g2, s);
204 r[i] = fabs(calc_ctf1(amp1, gamma, s));
205 s += ds;
206 }
207 break;
208
209 case CTF_SIGN:
210 for (int i = 0; i < np; i++) {
211 float gamma = calc_gamma(g1, g2, s);
212 r[i] = calc_ctf1(amp1, gamma, s)>0?1.0f:-1.0f;
213 s += ds;
214 }
215 break;
216
217 case CTF_BACKGROUND:
218 for (int i = 0; i < np; i++) {
219 r[i] = calc_noise(s);
220 s += ds;
221 }
222 break;
223
224 case CTF_SNR:
225 case CTF_SNR_SMOOTH:
226// if (!sf) {
227// LOGERR("CTF computation error, no SF found\n");
228// return r;
229// }
230
231 for (int i = 0; i < np; i++) {
232 float gamma = calc_gamma(g1, g2, s);
233 r[i] = calc_snr(amp1, gamma, s);
234 if (s && sf) {
235 r[i] *= sf->get_yatx(s);
236 }
237 s += ds;
238 }
239
240 break;
241
243 if (!sf) {
244 LOGERR("CTF computation error, no SF found\n");
245 return r;
246 }
247
248 for (int i = 0; i < np; i++) {
249 float gamma = calc_gamma(g1, g2, s);
250 r[i] = calc_snr(amp1, gamma, s);
251 if (s && sf) {
252 r[i] *= sf->get_yatx(s);
253 }
254
255 r[i] = 1.0f / (1.0f + 1.0f / r[i]);
256 s += ds;
257 }
258 break;
259
260 case CTF_TOTAL:
261 if (!sf) {
262 LOGERR("CTF computation error, no SF found\n");
263 return r;
264 }
265
266 for (int i = 0; i < np; i++) {
267 float gamma = calc_gamma(g1, g2, s);
268 if (sf) {
269 r[i] = calc_ctf1(amp1, gamma, s);
270 r[i] = r[i] * r[i] * sf->get_yatx(s) + calc_noise(s);
271 }
272 else {
273 r[i] = calc_ctf1(amp1, gamma, s);
274 r[i] = r[i] * r[i] + calc_noise(s);
275 }
276 s += ds;
277 }
278 break;
279 default:
280 break;
281 }
282
283 return r;
284}
285
286
288{
289
290
291}
292
293vector <float> EMAN1Ctf::compute_1d_fromimage(int size, float ds, EMData *image)
294{
295 vector < float >r;
296
297 printf("Sorry, this function hasn't been implemented for EMAN1Ctf\n");
298
299 int np=size/2;
300 r.resize(np);
301
302 return r;
303}
304
305
307{
308 // Discovered that whomever wrote these apparently never tested them. They do not follow the correct
309 // conventions, and the results are rubbish!
310 throw InvalidParameterException("EMAN1Ctf compute_2d_complex is broken, please use EMAN2Ctf instead");
311
312 if (!image) {
313 LOGERR("image is null. cannot computer 2D complex CTF");
314 return;
315 }
316
317 if (image->is_complex() == false) {
318 LOGERR("compute_2d_complex can only work on complex images");
319 return;
320 }
321
322 int nx = image->get_xsize();
323 int ny = image->get_ysize();
324
325 if (nx != ny + 2) {
326 LOGERR("compute_2d_complex only works on (nx, nx-2) images");
327 return;
328 }
329
330 float ds = 1.0f / (apix * ny);
331 image->to_one();
332
333 float *d = image->get_data();
334 float g1 = calc_g1();
335 float g2 = calc_g2();
336
337 if (type == CTF_BACKGROUND) {
338 for (int y = 0; y < ny; y++) {
339 int ynx = y * nx;
340
341 for (int x = 0; x < nx / 2; x++) {
342 float s = (float) hypot(x, y - ny / 2.0f) * ds;
343 d[x * 2 + ynx] = calc_noise(s);
344 d[x * 2 + ynx + 1] = 0; // The phase is somewhat arbitrary
345 }
346 }
347 }
348 else if (type == CTF_AMP) {
349 for (int y = 0; y < ny; y++) {
350 int ynx = y * nx;
351
352 for (int x = 0; x < nx / 2; x++) {
353 float s = (float)hypot((float) x, (float) y - ny / 2) * ds;
354 float gamma = calc_gamma(g1, g2, s);
355// float v = fabs(calc_amplitude(gamma)); // There should NOT be an fabs() here! 10/30/18
356 float v = calc_amplitude(gamma);
357 d[x * 2 + ynx] = v;
358 d[x * 2 + ynx + 1] = 0;
359 }
360 }
361 }
362 else if (type == CTF_ABS) {
363 for (int y = 0; y < ny; y++) {
364 int ynx = y * nx;
365
366 for (int x = 0; x < nx / 2; x++) {
367 float s = (float)hypot((float) x, (float) y - ny / 2) * ds;
368 float gamma = calc_gamma(g1, g2, s);
369// float v = fabs(calc_amplitude(gamma)); // There should NOT be an fabs() here! 10/30/18
370 float v = calc_amplitude(gamma);
371 d[x * 2 + ynx] = fabs(v);
372 d[x * 2 + ynx + 1] = 0;
373 }
374 }
375 }
376 else if (type == CTF_SIGN) {
377 for (int y = 0; y < ny; y++) {
378 int ynx = y * nx;
379 for (int x = 0; x < nx / 2; x++) {
380 float s = (float)hypot(x, y - ny / 2.0f) * ds;
381 float gamma = calc_gamma(g1, g2, s);
382 float v = calc_amplitude(gamma);
383 d[x * 2 + ynx] = v > 0 ? 1.0f : -1.0f;
384 d[x * 2 + ynx + 1] = 0;
385 }
386 }
387
388 }
389 else if (type == CTF_SNR || type == CTF_SNR_SMOOTH) {
390 float amp1 = calc_amp1();
391
392 for (int y = 0; y < ny; y++) {
393 int ynx = y * nx;
394
395 for (int x = 0; x < nx / 2; x++) {
396
397 float s = (float)hypot(x, y - ny / 2.0f) * ds;
398 float gamma = calc_gamma(g1, g2, s);
399 float f = calc_ctf1(amp1, gamma, s);
400 float noise = calc_noise(s);
401 f = f * f / noise;
402
403 if (s && sf) {
404 f *= sf->get_yatx(s);
405 }
406 d[x * 2 + ynx] *= f;
407 d[x * 2 + ynx + 1] = 0;
408 }
409 }
410 }
411 else if (type == CTF_WIENER_FILTER) {
412 float amp1 = calc_amp1();
413
414 for (int y = 0; y < ny; y++) {
415 int ynx = y * nx;
416
417 for (int x = 0; x < nx / 2; x++) {
418
419 float s = (float)hypot(x, y - ny / 2.0f) * ds;
420 float gamma = calc_gamma(g1, g2, s);
421 float f = calc_ctf1(amp1, gamma, s);
422 float noise = calc_noise(s);
423 f = f * f / noise;
424
425 if (s) {
426 f *= sf->get_yatx(s);
427 }
428 f = 1.0f / (1.0f + 1.0f / f);
429 d[x * 2 + ynx] *= f;
430 d[x * 2 + ynx + 1] = 0;
431 }
432 }
433 }
434 else if (type == CTF_TOTAL) {
435 float amp1 = calc_amp1();
436
437 for (int y = 0; y < ny; y++) {
438 int ynx = y * nx;
439
440 for (int x = 0; x < nx / 2; x++) {
441
442 float s = (float)hypot(x, y - ny / 2.0f) * ds;
443 float gamma = calc_gamma(g1, g2, s);
444 float f = calc_ctf1(amp1, gamma, s);
445 float noise = calc_noise(s);
446 f = f * f;
447
448 if (sf && s) {
449 f *= sf->get_yatx(s);
450 }
451 f+=noise;
452
453 d[x * 2 + ynx] *= f;
454 d[x * 2 + ynx + 1] = 0;
455 }
456 }
457 }
458
459 image->update();
460}
461
462
463
464bool EMAN1Ctf::equal(const Ctf * ctf1) const
465{
466 if (ctf1) {
467 const EMAN1Ctf *c = static_cast<const EMAN1Ctf *>(ctf1);
468 if (defocus == c->defocus &&
469 bfactor == c->bfactor &&
470 amplitude == c->amplitude &&
471 ampcont == c->ampcont &&
472 noise1 == c->noise1 &&
473 noise2 == c->noise2 &&
474 noise3 == c->noise3 &&
475 noise4 == c->noise4 && voltage == c->voltage && cs == c->cs && apix == c->apix) {
476 return true;
477 }
478 }
479 return false;
480}
481
482float EMAN1Ctf::zero(int n) const { return 0; }
483
484/*************************************
485EMAN2Ctf
486*************************************/
487
489{
490 defocus = 0;
491 dfdiff = 0;
492 dfang = 0;
493 bfactor = 0;
494 ampcont = 0;
495 voltage = 0;
496 cs = 0;
497 apix = 1.0;
498 dsbg=-1;
499 background.clear();
500 snr.clear();
501}
502
503
505{
506}
507
508
509int EMAN2Ctf::from_string(const string & ctf)
510{
511 Assert(ctf != "");
512 char type=' ';
513 int pos=-1,i,j;
514 int bglen=0,snrlen=0;
515 float v;
516 const char *s=ctf.c_str();
517
518 sscanf(s, "%c%f %f %f %f %f %f %f %f %f %d%n",
519 &type,&defocus, &dfdiff,&dfang,&bfactor,&ampcont,&voltage, &cs, &apix,&dsbg,&bglen,&pos);
520 if (type!='E') throw InvalidValueException(type,"Trying to initialize Ctf object with bad string");
521 if (pos==-1) throw InvalidValueException(s," Invalid CTF string");
522
523
524 background.resize(bglen);
525 for (i=0; i<bglen; i++) {
526 if (sscanf(s+pos,",%f%n",&v,&j)<1) return(1);
527 background[i]=v;
528 pos+=j;
529 }
530
531 sscanf(s+pos," %d%n",&snrlen,&j);
532 pos+=j;
533 snr.resize(snrlen);
534 for (i=0; i<snrlen; i++) {
535 if (sscanf(s+pos,",%f%n",&v,&j)<1) return(1);
536 snr[i]=v;
537 pos+=j;
538 }
539
540 return 0;
541
542}
543
545{
546 char ctf[256];
547 sprintf(ctf, "E%1.10g %1.10g %1.10g %1.10g %1.10g %1.10g %1.10g %1.10g %1.10g %d",
549
550 string ret=ctf;
551 for (int i=0; i<(int)background.size(); i++) {
552 sprintf(ctf,",%1.3g",background[i]);
553 ret+=ctf;
554 }
555
556 sprintf(ctf, " %d",(int)snr.size());
557 ret+=ctf;
558 for (int i=0; i<(int)snr.size(); i++) {
559 sprintf(ctf,",%1.3g",snr[i]);
560 ret+=ctf;
561 }
562
563
564 return ret;
565}
566
567void EMAN2Ctf::from_dict(const Dict & dict)
568{
569// printf("st\n");
570 defocus = (float)dict["defocus"];
571// printf("df\n");
572 dfdiff = (float)dict["dfdiff"];
573// printf("dfd\n");
574 dfang = (float)dict["dfang"];
575// printf("dfa\n");
576 bfactor = (float)dict["bfactor"];
577// printf("bf\n");
578 ampcont = (float)dict["ampcont"];
579// printf("ac\n");
580 voltage = (float)dict["voltage"];
581// printf("vo\n");
582 cs = (float)dict["cs"];
583// printf("cs\n");
584 apix = (float)dict["apix"];
585// printf("ap\n");
586 dsbg = (float)dict["dsbg"];
587// printf("ds\n");
588 background = dict["background"];
589// printf("bg\n");
590 snr = dict["snr"];
591// printf("done\n");
592}
593
595{
596 Dict dict;
597 dict["defocus"] = defocus;
598 dict["dfdiff"] = dfdiff;
599 dict["dfang"] = dfang;
600 dict["bfactor"] = bfactor;
601 dict["ampcont"] = ampcont;
602 dict["voltage"] = voltage;
603 dict["cs"] = cs;
604 dict["apix"] = apix;
605 dict["dsbg"] = dsbg;
606 dict["background"] = background;
607 dict["snr"] = snr;
608
609 return dict;
610}
611
612void EMAN2Ctf::from_vector(const vector<float>& vctf)
613{
614 int i;
615 defocus = vctf[0];
616 dfdiff = vctf[1];
617 dfang = vctf[2];
618 bfactor = vctf[3];
619 ampcont = vctf[4];
620 voltage = vctf[5];
621 cs = vctf[6];
622 apix = vctf[7];
623 dsbg = vctf[8];
624 background.resize((int)vctf[9]);
625 for (i=0; i<(int)vctf[9]; i++) background[i]=vctf[i+10];
626 snr.resize((int)vctf[i+10]);
627 for (int j=0; j<(int)vctf[i+10]; j++) snr[j]=vctf[i+j+11];
628}
629
630vector<float> EMAN2Ctf::to_vector() const
631{
632 vector<float> vctf;
633
634 vctf.push_back(defocus);
635 vctf.push_back(dfdiff);
636 vctf.push_back(dfang);
637 vctf.push_back(bfactor);
638 vctf.push_back(ampcont);
639 vctf.push_back(voltage);
640 vctf.push_back(cs);
641 vctf.push_back(apix);
642 vctf.push_back(dsbg);
643 vctf.push_back((float)background.size());
644 for (unsigned int i=0; i<background.size(); i++) vctf.push_back(background[i]);
645 vctf.push_back((float)snr.size());
646 for (unsigned int j=0; j<snr.size(); j++) vctf.push_back(snr[j]);
647
648 return vctf;
649}
650
651
652
653void EMAN2Ctf::copy_from(const Ctf * new_ctf)
654{
655 if (new_ctf) {
656 const EMAN2Ctf *c = static_cast<const EMAN2Ctf *>(new_ctf);
657 defocus = c->defocus;
658 dfdiff = c->dfdiff;
659 dfang = c->dfang;
660 bfactor = c->bfactor;
661 ampcont = c->ampcont;
662 voltage = c->voltage;
663 cs = c->cs;
664 apix = c->apix;
665 dsbg = c->dsbg;
667 snr = c->snr;
668 }
669}
670
671float EMAN2Ctf::get_phase() const {
672 if (ampcont>-100.0 && ampcont<=100.0) return asin(ampcont/100.0);
673 if (ampcont>100.0) return M_PI-asin(2.0f-ampcont/100.0);
674 return -M_PI-asin(-2.0-ampcont/100.0);
675}
676
678 if (phase>=-M_PI/2.0f && phase<M_PI/2.0f) ampcont=sin(phase)*100.0;
679 else if (phase>=M_PI/2.0f && phase<=M_PI) ampcont=(2.0-sin(phase))*100.0;
680 else if (phase>-M_PI && phase<-M_PI/2.0f) ampcont=(-2.0-sin(phase))*100.0;
681 else printf("Phase = %0.4f deg out of range\n",phase*180.0/M_PI);
682
683}
684
685vector <float> EMAN2Ctf::compute_1d_fromimage(int size, float ds, EMData *image)
686{
687 size/=2; // to be consistent with the next routine
688 vector <float> ret(size);
689 vector <float> norm(size);
690
691 if (!image->is_complex() || !image->is_ri()) ImageFormatException("EMAN2Ctf::compute_1d_fromimage requires a complex, ri image");
692 int isinten=image->get_attr_default("is_intensity",0);
693 if (isinten) ImageFormatException("EMAN2Ctf::compute_1d_fromimage does not take intensity images");
694
695 int nx=image->get_attr("nx");
696 int ny=image->get_attr("ny");
697 float *data=image->get_data();
698
699 int x,y,i;
700 for (y=i=0; y<ny; y++) {
701 for (x=0; x<nx; x+=2,i+=2) {
702 if (x==0 && y>ny/2) continue;
703 float r=(float)(Util::hypot_fast(x/2,y<ny/2?y:ny-y)); // origin at 0,0; periodic
704 float a=(float)atan2((float)(y<ny/2?y:ny-y),(float)(x/2)); // angle to point (radians)
705 r=stos2(r*ds,-dfdiff/2*cos(2.0*a-2.0*M_PI/180.0*dfang))/ds; // angle-based defocus -> convert s to remove astigmatism, dfang in degrees
706 int f=int(r); // safe truncation, so floor isn't needed
707 r-=float(f); // r is now the fractional spacing between bins
708
709 float v=Util::square_sum(data[i],data[i+1]); //intensity
710 if (f>=0 && f<size) {
711 ret[f]+=v*(1.0f-r);
712 norm[f]+=(1.0f-r);
713 if (f<size-1) {
714 ret[f+1]+=v*r;
715 norm[f+1]+=r;
716 }
717 }
718 }
719 }
720
721 for (i=0; i<size; i++) ret[i]/=norm[i]?norm[i]:1.0f; // Normalize
722
723
724 return ret;
725}
726
727
728inline int max_int(int a,int b) { return a>b?a:b; }
729inline int min_int(int a,int b) { return a<b?a:b; }
730
731vector <float> EMAN2Ctf::compute_1d(int size,float ds, CtfType type, XYData * sf)
732{
733 Assert(size > 0);
734
735// float tmp_f1 = sqrt((float) 2) * size / 2;
736// int np = (int) ceil(tmp_f1) + 2;
737 int np=size/2;
738 vector < float >r;
739
740 r.resize(np);
741
742 float s = 0;
743 float g1=M_PI/2.0*cs*1.0e7*pow(lambda(),3.0f); // s^4 coefficient for gamma, cached in a variable for simplicity (maybe speed? depends on the compiler)
744 float g2=M_PI*lambda()*defocus*10000.0; // s^2 coefficient for gamma
745// float acac=acos(ampcont/100.0); // instead of ac*cos(g)+sqrt(1-ac^2)*sin(g), we can use cos(g-acos(ac)) and save a trig op
746 float acac=M_PI/2.0-get_phase();
747 switch (type) {
748 case CTF_AMP:
749 for (int i = 0; i < np; i++) {
750 float gam=-g1*s*s*s*s+g2*s*s;
751 r[i] = cos(gam-acac)*exp(-(bfactor/4.0f * s * s));
752 s += ds;
753 }
754 break;
755
756 case CTF_ABS:
757 for (int i = 0; i < np; i++) {
758 float gam=-g1*s*s*s*s+g2*s*s;
759 r[i] = fabs(cos(gam-acac)*exp(-(bfactor/4.0f * s * s)));
760 s += ds;
761 }
762 break;
763
764 case CTF_INTEN:
765 for (int i = 0; i < np; i++) {
766 float gam=-g1*s*s*s*s+g2*s*s;
767 r[i] = cos(gam-acac)*exp(-(bfactor/4.0f * s*s));
768 r[i]*=r[i];
769 s += ds;
770 }
771 break;
772
773 case CTF_SIGN:
774 for (int i = 0; i < np; i++) {
775 float gam=-g1*s*s*s*s+g2*s*s;
776 r[i] = cos(gam-acac)<0?-1.0:1.0;
777 s += ds;
778 }
779 break;
780
781 case CTF_BACKGROUND:
782 for (int i = 0; i < np; i++) {
783 float f = s/dsbg;
784 int j = (int)floor(f);
785 f-=j;
786 if (j>(int)background.size()-2) r[i]=background.back();
787 else r[i]=background[j]*(1.0f-f)+background[j+1]*f;
788 s+=ds;
789 }
790 break;
791
792 case CTF_SNR:
793 if (snr.size()<1) {
794 throw InvalidValueException("CTF_SNR"," ERROR: No SNR info in CTF header.");
795 break;
796 }
797 for (int i = 0; i < np; i++) {
798 float f = s/dsbg;
799 int j = (int)floor(f);
800 f-=j;
801 if (j>(int)snr.size()-2) r[i]=snr.back();
802 else r[i]=snr[j]*(1.0f-f)+snr[j+1]*f;
803// printf("%d\t%f\n",j,snr[j]);
804 s+=ds;
805 }
806 break;
807 case CTF_SNR_SMOOTH:
808 // This apparently complicated routine tries to make a nice smooth and accurate SNR curve. It does this
809 // by fitting local regions of the SNR vs the theoretical SNR (theoretical CTF^2/measured background),
810 // then taking the slope of the result times the theoretical SNR to produce a local SNR estimate
811
812 { // <- is to permit new temporary value allocation
813 vector < float >tsnr; // theoretical SNR
814 tsnr.resize(np);
815 vector < float >dsnr; // data SNR
816 dsnr.resize(np);
817
818 float s0=s;
819
820 for (int i = 0; i < np; i++) {
821 float gam=-g1*s*s*s*s+g2*s*s;
822 tsnr[i] = cos(gam-acac)*exp(-(bfactor/4.0f * s * s)); // ctf amp
823
824 // background value
825 float f = s/dsbg;
826 int j = (int)floor(f);
827 f-=j;
828 float bg;
829 if (j>(int)background.size()-2) bg=background.back();
830 else bg=background[j]*(1.0f-f)+background[j+1]*f;
831 if (bg <=0) bg=.001f;
832
833 tsnr[i] = tsnr[i]*tsnr[i]/bg; // This is now a SNR curve
834 if (sf && s) {
835 tsnr[i] *= sf->get_yatx(s);
836 }
837
838
839 // This is the SNR computed from the data without fitting
840 if (j>(int)snr.size()-2) dsnr[i]=snr.back();
841 else dsnr[i]=snr[j]*(1.0f-f)+snr[j+1]*f;
842
843 s+=ds;
844 }
845
846 int npsm=np/25; // 1/2 number of points to smooth over, 25 is arbitrary
847 if (npsm<2) npsm=2;
848
849 s=s0;
850 for (int i = 1; i < np; i++) {
851 // simple linear regression embedded here
852 double sum = 0;
853 double sum_x = 0;
854 double sum_y = 0;
855 double sum_xx = 0;
856 double sum_xy = 0;
857
858 for (int k=max_int(i-npsm,1); k<=min_int(i+npsm,np-1); k++) {
859 double y = dsnr[k];
860 double x = tsnr[k];
861
862 sum_x += x;
863 sum_y += y;
864 sum_xx += x * x;
865 sum_xy += x * y;
866 sum++;
867 }
868
869 double div = sum * sum_xx - sum_x * sum_x;
870// if (div == 0) {
871// div = 0.0000001f;
872// }
873
874 // *intercept = (float) ((sum_xx * sum_y - sum_x * sum_xy) / div);
875 // *slope = (float) ((sum * sum_xy - sum_x * sum_y) / div);
876
877 if (div!=0.0) r[i]=(float) ((sum * sum_xy - sum_x * sum_y) / div)*tsnr[i];
878 else r[i]=0.0;
879 if (r[i]<0) r[i]=0;
880
881 s+=ds;
882 }
883 r[0]=0;
884 }
885 break;
886
888// if (!sf) {
889// LOGERR("CTF computation error, no SF found\n");
890// return r;
891// }
892
893 for (int i = 0; i < np; i++) {
894 float f = s/dsbg;
895 int j = (int)floor(f);
896 float bg;
897 f-=j;
898 if (j>(int)snr.size()-2) {
899/* r[i]=snr.back();
900 bg=background.back();*/
901 r[i]=0;
902 }
903 else {
904 r[i]=snr[j]*(1.0f-f)+snr[j+1]*f;
905 bg=background[j]*(1.0f-f)+background[j+1]*f;
906 }
907 if (r[i]<0) r[i]=0;
908 r[i]=r[i]/(r[i]+1.0f); // Full Wiener filter assuming perfect image with noise
909// r[i]=sqrt(r[i]/bg)/(r[i]+1.0); // Wiener filter with 1/CTF term (sort of) to restore image then filter
910 s+=ds;
911 }
912 r[0]=0;
913 break;
914
915 case CTF_TOTAL:
916
917 for (int i = 0; i < np; i++) {
918 float gam=-g1*s*s*s*s+g2*s*s;
919 if (sf) {
920 r[i] = cos(gam-acac)*exp(-(bfactor/4.0f * s*s));
921 r[i] = r[i] * r[i] * sf->get_yatx(s) + calc_noise(s);
922 }
923 else {
924 r[i] = cos(gam-acac)*exp(-(bfactor/4.0f * s*s));
925 r[i] = r[i] * r[i] + calc_noise(s);
926 }
927 s += ds;
928 }
929 break;
930 case CTF_NOISERATIO:
931 for (int i = 0; i < np; i++) {
932 float gam=-g1*s*s*s*s+g2*s*s;
933 if (sf) {
934 r[i] = cos(gam-acac)*exp(-(bfactor/4.0f * s*s));
935 r[i] = r[i] * r[i] * sf->get_yatx(s);
936 r[i] = r[i]/(r[i]+calc_noise(s));
937 }
938 else {
939 r[i] = cos(gam-acac)*exp(-(bfactor/4.0f * s*s));
940 r[i] = r[i] * r[i];
941 r[i] = r[i]/(r[i]+calc_noise(s));
942 }
943
944 s+=ds;
945 }
946
947 break;
948 default:
949 break;
950 }
951
952 return r;
953}
954
955
957{
958
959
960}
961
962
963
965{
966 if (!image) {
967 LOGERR("image is null. cannot computer 2D complex CTF");
968 return;
969 }
970
971 if (image->is_complex() == false) {
972 LOGERR("compute_2d_complex can only work on complex images");
973 return;
974 }
975
976 int nx = image->get_xsize();
977 int ny = image->get_ysize();
978
979 if ((ny%2==1 && nx!=ny+1) || (ny%2==0 && nx != ny + 2)) {
980 printf("nx=%d ny=%d\n",nx,ny);
981 LOGERR("compute_2d_complex only works on (nx, nx-2) images");
982 return;
983 }
984
985 float ds = 1.0f / (apix * ny);
986 image->to_one();
987
988 float *d = image->get_data();
989 float g1=M_PI/2.0*cs*1.0e7*pow(lambda(),3.0f); // s^4 coefficient for gamma, cached in a variable for simplicity (maybe speed? depends on the compiler)
990 float g2=M_PI*lambda()*10000.0; // s^2 coefficient for gamma
991// float acac=acos(ampcont/100.0); // instead of ac*cos(g)+sqrt(1-ac^2)*sin(g), we can use cos(g-acos(ac)) and save a trig op
992 float acac=M_PI/2.0-get_phase();
993
994 if (type == CTF_BACKGROUND) {
995 for (int y = -ny/2; y < ny/2; y++) {
996 int y2=(y+ny)%ny;
997 int ynx = y2 * nx;
998
999 for (int x = 0; x < nx / 2; x++) {
1000 float s = (float) Util::hypot_fast(x, y ) * ds;
1001 d[x * 2 + ynx] = calc_noise(s);
1002 d[x * 2 + ynx + 1] = 0; // The phase is somewhat arbitrary
1003 }
1004 }
1005 }
1006 else if (type == CTF_AMP) {
1007 for (int y = -ny/2; y < ny/2; y++) {
1008 int y2=(y+ny)%ny;
1009 int ynx = y2 * nx;
1010
1011 for (int x = 0; x < nx / 2; x++) {
1012 float s = (float)Util::hypot_fast(x,y ) * ds;
1013 float gam;
1014 if (dfdiff==0) gam=-g1*s*s*s*s+g2*defocus*s*s;
1015 else gam=-g1*s*s*s*s+g2*df(atan2((float)y,(float)x))*s*s;
1016 float v = cos(gam-acac)*exp(-(bfactor/4.0f * s*s));
1017 d[x * 2 + ynx] = v;
1018 d[x * 2 + ynx + 1] = 0;
1019 }
1020 }
1021 }
1022 else if (type == CTF_ABS) {
1023 for (int y = -ny/2; y < ny/2; y++) {
1024 int y2=(y+ny)%ny;
1025 int ynx = y2 * nx;
1026
1027 for (int x = 0; x < nx / 2; x++) {
1028 float s = (float)Util::hypot_fast(x,y ) * ds;
1029 float gam;
1030 if (dfdiff==0) gam=-g1*s*s*s*s+g2*defocus*s*s;
1031 else gam=-g1*s*s*s*s+g2*df(atan2((float)y,(float)x))*s*s;
1032 float v = cos(gam-acac)*exp(-(bfactor/4.0f * s*s));
1033 d[x * 2 + ynx] = fabs(v);
1034 d[x * 2 + ynx + 1] = 0;
1035 }
1036 }
1037 }
1038 else if (type == CTF_INTEN) {
1039 for (int y = -ny/2; y < ny/2; y++) {
1040 int y2=(y+ny)%ny;
1041 int ynx = y2 * nx;
1042
1043 for (int x = 0; x < nx / 2; x++) {
1044 float s = (float)Util::hypot_fast(x,y ) * ds;
1045 float gam;
1046 if (dfdiff==0) gam=-g1*s*s*s*s+g2*defocus*s*s;
1047 else gam=-g1*s*s*s*s+g2*df(atan2((float)y,(float)x))*s*s;
1048 float v = cos(gam-acac)*exp(-(bfactor/4.0f * s*s));
1049 d[x * 2 + ynx] = v*v;
1050 d[x * 2 + ynx + 1] = 0;
1051 }
1052 }
1053 }
1054 else if (type == CTF_POWEVAL) {
1055 for (int y = -ny/2; y < ny/2; y++) {
1056 int y2=(y+ny)%ny;
1057 int ynx = y2 * nx;
1058
1059 for (int x = 0; x < nx / 2; x++) {
1060 float s = (float)Util::hypot_fast(x,y ) * ds;
1061 float gam;
1062 // mf is used to gradually "turn on" the curve as we approach 20 A
1063 float mf=1.0;
1064 if (s<.04) mf=0.0;
1065 else if (s<.05) mf=1.0-exp(-pow((s-.04f)*300.0f,2.0f));
1066 if (dfdiff==0) gam=-g1*s*s*s*s+g2*defocus*s*s;
1067 else gam=-g1*s*s*s*s+g2*df(atan2((float)y,(float)x))*s*s;
1068 float v = cos(gam-acac);
1069 if (v>0.9) v=exp(-(50.0f/4.0f * s*s));
1070 else v=0;
1071 d[x * 2 + ynx] = mf*v*v;
1072 d[x * 2 + ynx + 1] = 0;
1073 }
1074 }
1075 }
1076 else if (type == CTF_SIGN) {
1077 for (int y = -ny/2; y < ny/2; y++) {
1078 int y2=(y+ny)%ny;
1079 int ynx = y2 * nx;
1080 for (int x = 0; x < nx / 2; x++) {
1081 float s = (float)Util::hypot_fast(x,y ) * ds;
1082 float gam;
1083 if (dfdiff==0) gam=-g1*s*s*s*s+g2*defocus*s*s;
1084 else gam=-g1*s*s*s*s+g2*df(atan2((float)y,(float)x))*s*s;
1085 float v = cos(gam-acac);
1086 d[x * 2 + ynx] = v<0?-1.0:1.0;
1087 d[x * 2 + ynx + 1] = 0;
1088 }
1089 }
1090 }
1091 else if (type == CTF_FITREF) {
1092 for (int y = -ny/2; y < ny/2; y++) {
1093 int y2=(y+ny)%ny;
1094 int ynx = y2 * nx;
1095
1096 for (int x = 0; x < nx / 2; x++) {
1097 float s = (float)Util::hypot_fast(x,y ) * ds;
1098 // We exclude very low frequencies from consideration due to the strong structure factor
1099 if (s<.04) {
1100 d[x * 2 + ynx] = 0;
1101 d[x * 2 + ynx + 1] = 0;
1102 continue;
1103 }
1104 // Rather than suddenly "turning on" the CTF, we do it gradually
1105 float mf=1.0;
1106 if (s<.05) {
1107 mf=1.0-exp(-pow((s-.04f)*300.0f,2.0f));
1108 }
1109 float gam;
1110 if (dfdiff==0) gam=-g1*s*s*s*s+g2*defocus*s*s;
1111 else gam=-g1*s*s*s*s+g2*df(atan2((float)y,(float)x))*s*s;
1112 float v = cos(gam-acac)*exp(-(bfactor/4.0f * s*s));
1113 d[x * 2 + ynx] = mf*v*v;
1114 d[x * 2 + ynx + 1] = 0;
1115 }
1116 }
1117 }
1118 else if (type == CTF_SNR) {
1119
1120 for (int y = -ny/2; y < ny/2; y++) {
1121 int y2=(y+ny)%ny;
1122 int ynx = y2 * nx;
1123
1124 for (int x = 0; x < nx / 2; x++) {
1125
1126 float s = (float)Util::hypot_fast(x,y ) * ds;
1127 float f = s/dsbg;
1128 int j = (int)floor(f);
1129 f-=j;
1130 if (j>(int)snr.size()-2) d[x*2+ynx]=snr.back();
1131 else d[x*2+ynx]=snr[j]*(1.0f-f)+snr[j+1]*f;
1132 d[x * 2 + ynx + 1] = 0;
1133 }
1134 }
1135 d[0]=0;
1136 }
1137 else if (type == CTF_SNR_SMOOTH) {
1138 for (int y = -ny/2; y < ny/2; y++) {
1139 int y2=(y+ny)%ny;
1140 int ynx = y2 * nx;
1141
1142 for (int x = 0; x < nx / 2; x++) {
1143
1144 float s = (float)Util::hypot_fast(x,y ) * ds;
1145 float f = s/dsbg;
1146 int j = (int)floor(f);
1147 f-=j;
1148 if (j>(int)snr.size()-2) d[x*2+ynx]=snr.back();
1149 else d[x*2+ynx]=snr[j]*(1.0f-f)+snr[j+1]*f;
1150 d[x * 2 + ynx + 1] = 0;
1151 }
1152 }
1153 d[0]=0;
1154 }
1155 else if (type == CTF_WIENER_FILTER) {
1156 if (dsbg==0) printf("Warning, DSBG set to 0\n");
1157 for (int y = -ny/2; y < ny/2; y++) {
1158 int y2=(y+ny)%ny;
1159 int ynx = y2 * nx;
1160
1161 for (int x = 0; x < nx / 2; x++) {
1162
1163 float s = (float)Util::hypot_fast(x,y ) * ds;
1164 float f = s/dsbg;
1165 int j = (int)floor(f);
1166 float bg,snrf;
1167 f-=j;
1168 if (j>(int)snr.size()-2) {
1169/* bg=background.back();
1170 d[x*2+ynx]=snr.back()/(snr.back()+1.0);*/
1171 d[x*2+ynx]=0;
1172 }
1173 else {
1174 bg=background[j]*(1.0f-f)+background[j+1]*f;
1175 snrf=snr[j]*(1.0f-f)+snr[j+1]*f;
1176
1177// printf("%d\t%f\n",x,sqrt(snrf/bg)/(snrf+1.0));
1178 if (snrf<0) snrf=0.0;
1179// d[x*2+ynx]=sqrt(snrf/bg)/(snrf+1.0); // Note that this is a Wiener filter with a 1/CTF term to compensate for the filtration already applied, but needs to be multiplied by the structure factor
1180 d[x*2+ynx]=snrf/(snrf+1); // This is just the simple Wiener filter
1181
1182 }
1183 d[x * 2 + ynx + 1] = 0;
1184 }
1185 }
1186 d[0]=0;
1187 }
1188 else if (type == CTF_TOTAL) {
1189
1190 for (int y = -ny/2; y < ny/2; y++) {
1191 int y2=(y+ny)%ny;
1192 int ynx = y2 * nx;
1193
1194 for (int x = 0; x < nx / 2; x++) {
1195 float s = (float)Util::hypot_fast(x,y ) * ds;
1196 float gam;
1197 if (dfdiff==0) gam=-g1*s*s*s*s+g2*defocus*s*s;
1198 else gam=-g1*s*s*s*s+g2*df(atan2((float)y,(float)x))*s*s;
1199 float v = cos(gam-acac)*exp(-(bfactor/4.0f * s*s));
1200 d[x * 2 + ynx] = v*v+calc_noise(s);
1201 d[x * 2 + ynx + 1] = 0;
1202// if ((x==101||x==100) && y2==79) printf("%f %f %f %f\n",s,gam,v,d[x * 2 + ynx]);
1203 }
1204 }
1205 }
1206 else if (type == CTF_ALIFILT) {
1207 double vt=0;
1208 for (int y = -ny/2; y < ny/2; y++) {
1209 int y2=(y+ny)%ny;
1210 int ynx = y2 * nx;
1211
1212 for (int x = 0; x < nx / 2; x++) {
1213 float s = (float)Util::hypot_fast(x,y ) * ds;
1214 float gam;
1215 if (dfdiff==0) gam=-g1*s*s*s*s+g2*defocus*s*s;
1216 else gam=-g1*s*s*s*s+g2*df(atan2((float)y,(float)x))*s*s;
1217 // this make values near the zero crossings negative to cancel out 0,0 correlation
1218// float v = (pow(cos(gam-acac),2.0)-0.5)*exp(-(bfactor/4.0f * s*s));
1219 // Basically just a CTF weight
1220 float v = (pow((float)cos(gam-acac),2.0f))*exp(-(bfactor/4.0f * s*s));
1221 //v*=v;
1222 //v=fabs(v);
1223 d[x * 2 + ynx] = v;
1224 d[x * 2 + ynx + 1] = 0;
1225 vt+=v;
1226 }
1227 }
1228 vt/=nx*ny/2;
1229// for (size_t i=0; i<image->get_xsize()*image->get_ysize(); i+=2) d[i]=(d[i]-vt)<0?-1.0:1.0;
1230// for (size_t i=0; i<image->get_xsize()*image->get_ysize(); i+=2) d[i]=(d[i]-vt);
1231 }
1232 else printf("Unknown CTF image mode\n");
1233
1234 image->update();
1235}
1236
1237
1238
1239bool EMAN2Ctf::equal(const Ctf * ctf1) const
1240{
1241 if (ctf1) {
1242 const EMAN2Ctf *c = static_cast<const EMAN2Ctf *>(ctf1);
1243 if (defocus != c->defocus ||
1244 dfdiff != c->dfdiff ||
1245 dfang != c->dfang ||
1246 bfactor != c->bfactor ||
1247 ampcont != c->ampcont ||
1248 voltage != c->voltage ||
1249 cs != c->cs ||
1250 apix != c->apix ||
1251 dsbg != c->dsbg ||
1252 background.size() != c->background.size() ||
1253 snr.size() != c->snr.size()
1254 ) return false;
1255
1256 for (unsigned int i=0; i<background.size(); i++) {
1257 if (background[i]!=c->background[i]) return false;
1258 }
1259 for (unsigned int i=0; i<snr.size(); i++) {
1260 if (snr[i]!=c->snr[i]) return false;
1261 }
1262 return true;
1263 }
1264 return false;
1265}
1266
1267float EMAN2Ctf::zero(int n) const {
1268vector <float>zeroes;
1269float lam=lambda();
1270float acac=M_PI/2.0-get_phase();
1271
1272int m=n*2;
1273if (m<15) m=15; // A bit arbitrary. I believe this will always get us the zeroes we need in any practical situation
1274for (int i=-m; i<m; i++) {
1275 float r1=defocus*defocus*1.0e8 + cs*lam*1.0e7 - 2.0*cs*i*lam*1.0e7 - 2*cs*1.0e7*lam*acac/M_PI;
1276// printf("%f\n",r1);
1277 if (r1<0) continue;
1278 float r2=defocus*1.0e4+sqrt(r1);
1279 if (r2>0) zeroes.push_back(sqrt(r2/(cs*lam*lam*1.0e7)));
1280 float r2a=defocus*1.0e4-sqrt(r1);
1281 if (r2a>0) zeroes.push_back(sqrt(r2a/(cs*lam*lam*1.0e7)));
1282}
1283if (zeroes.size()==0) return 0.0f;
1284std::sort(zeroes.begin(),zeroes.end());
1285
1286return zeroes[n];
1287}
1288
1289
Ctf is the base class for all CTF model.
Definition: ctf.h:60
float cs
Definition: ctf.h:87
float bfactor
Definition: ctf.h:85
float voltage
Definition: ctf.h:86
float apix
Definition: ctf.h:88
float defocus
Definition: ctf.h:84
CtfType
Definition: ctf.h:64
@ CTF_TOTAL
Definition: ctf.h:71
@ CTF_FITREF
Definition: ctf.h:72
@ CTF_NOISERATIO
Definition: ctf.h:73
@ CTF_SNR_SMOOTH
Definition: ctf.h:69
@ CTF_WIENER_FILTER
Definition: ctf.h:70
@ CTF_AMP
Definition: ctf.h:65
@ CTF_ALIFILT
Definition: ctf.h:76
@ CTF_INTEN
Definition: ctf.h:74
@ CTF_SIGN
Definition: ctf.h:66
@ CTF_BACKGROUND
Definition: ctf.h:67
@ CTF_POWEVAL
Definition: ctf.h:75
@ CTF_SNR
Definition: ctf.h:68
@ CTF_ABS
Definition: ctf.h:77
Dict is a dictionary to store <string, EMObject> pair.
Definition: emobject.h:385
EMAN1Ctf is the CTF model used in EMAN1.
Definition: ctf.h:120
vector< float > compute_1d_fromimage(int size, float ds, EMData *image)
Definition: ctf.cpp:293
float amplitude
Definition: ctf.h:124
float calc_snr(float g1, float gamma, float s)
Definition: ctf.h:225
void from_vector(const vector< float > &vctf)
Definition: ctf.cpp:112
int from_string(const string &ctf)
Definition: ctf.cpp:60
float noise2
Definition: ctf.h:127
float calc_noise(float s)
Definition: ctf.h:217
void from_dict(const Dict &dict)
Definition: ctf.cpp:79
float noise4
Definition: ctf.h:129
float calc_g2()
Definition: ctf.h:190
float zero(int n) const
Definition: ctf.cpp:482
float calc_ctf1(float g, float gamma, float s)
Definition: ctf.h:204
void compute_2d_real(EMData *image, CtfType type, XYData *struct_factor=0)
Definition: ctf.cpp:287
float noise1
Definition: ctf.h:126
void copy_from(const Ctf *new_ctf)
Definition: ctf.cpp:157
float ampcont
Definition: ctf.h:125
vector< float > to_vector() const
Definition: ctf.cpp:127
float noise3
Definition: ctf.h:128
float calc_amp1()
Definition: ctf.h:172
string to_string() const
Definition: ctf.cpp:147
void compute_2d_complex(EMData *image, CtfType type, XYData *struct_factor=0)
Definition: ctf.cpp:306
Dict to_dict() const
Definition: ctf.cpp:94
float calc_g1()
Definition: ctf.h:183
float calc_gamma(float g1, float g2, float s)
Definition: ctf.h:197
vector< float > compute_1d(int size, float ds, CtfType type, XYData *struct_factor=0)
Definition: ctf.cpp:176
bool equal(const Ctf *ctf1) const
Definition: ctf.cpp:464
float calc_amplitude(float gamma)
Definition: ctf.h:210
EMAN2Ctf is the default CTF model used in EMAN2.
Definition: ctf.h:237
float df(float ang) const
Definition: ctf.h:300
float zero(int n) const
Definition: ctf.cpp:1267
string to_string() const
Definition: ctf.cpp:544
bool equal(const Ctf *ctf1) const
Definition: ctf.cpp:1239
float calc_noise(float s) const
Definition: ctf.h:305
void compute_2d_real(EMData *image, CtfType type, XYData *struct_factor=0)
Definition: ctf.cpp:956
float stos2(float s, float dZ)
Definition: ctf.h:280
vector< float > background
Definition: ctf.h:248
vector< float > snr
Definition: ctf.h:249
float dfdiff
Definition: ctf.h:240
void from_dict(const Dict &dict)
Definition: ctf.cpp:567
vector< float > compute_1d_fromimage(int size, float ds, EMData *image)
Definition: ctf.cpp:685
vector< float > compute_1d(int size, float ds, CtfType type, XYData *struct_factor=0)
Definition: ctf.cpp:731
void from_vector(const vector< float > &vctf)
Definition: ctf.cpp:612
vector< float > to_vector() const
Definition: ctf.cpp:630
float dfang
Definition: ctf.h:241
void copy_from(const Ctf *new_ctf)
Definition: ctf.cpp:653
void compute_2d_complex(EMData *image, CtfType type, XYData *struct_factor=0)
Definition: ctf.cpp:964
Dict to_dict() const
Definition: ctf.cpp:594
float get_phase() const
Definition: ctf.cpp:671
int from_string(const string &ctf)
Definition: ctf.cpp:509
float ampcont
Definition: ctf.h:243
float dsbg
Definition: ctf.h:247
float lambda() const
Definition: ctf.h:293
void set_phase(float phase)
Definition: ctf.cpp:677
EMData stores an image's data and defines core image processing routines.
Definition: emdata.h:82
static float square_sum(float x, float y)
Calcuate (x*x + y*y).
Definition: util.h:764
static float hypot_fast(int x, int y)
Euclidean distance in 2D for integers computed fast using a cached lookup table.
Definition: util.cpp:742
XYData defines a 1D (x,y) data set.
Definition: xydata.h:47
float get_yatx(float x, bool outzero=true)
Definition: xydata.cpp:172
int max_int(int a, int b)
Definition: ctf.cpp:728
int min_int(int a, int b)
Definition: ctf.cpp:729
#define Assert(s)
Define Assert() function that is effective only when -DDEBUG is used.
Definition: emassert.h:42
EMData * sqrt() const
return square root of current image
EMData * phase() const
return phase part of a complex image as a real image format
void div(float f)
make each pixel value divided by a float number.
#define InvalidParameterException(desc)
Definition: exception.h:361
#define InvalidValueException(val, desc)
Definition: exception.h:285
#define ImageFormatException(desc)
Definition: exception.h:147
#define LOGERR
Definition: log.h:51
E2Exception class.
Definition: aligner.h:40
#define y(i, j)
Definition: projector.cpp:1516
#define x(i)
Definition: projector.cpp:1517