| Bsoft 2.0.5 Bernard's software package

ctf.cpp
Go to the documentation of this file.
1
9 #include "ctf.h"
10 #include "utilities.h"
11
12 // Declaration of global variables
13 extern int verbose; // Level of output to the screen
14
20 int CTFparam::update(CTFparam& ctf)
21 {
22 int i;
23
24 if ( ctf.volt() ) volt(ctf.volt()); // Acceleration voltage (volts)
25 if ( ctf.Cs() ) Cs(ctf.Cs()); // CTF spherical aberation (angstrom)
26 if ( ctf.Cc() ) cc = ctf.Cc(); // CTF spherical aberation (angstrom)
27 if ( ctf.alpha() ) a = ctf.alpha(); // CTF spherical aberation (angstrom)
28 if ( ctf.dE() ) de = ctf.dE(); // CTF spherical aberation (angstrom)
29 if ( ctf.amp_shift() ) amp_shift(ctf.amp_shift()); // CTF amplitude phase shift (radians)
30 if ( ctf.defocus_average() ) def_avg = ctf.defocus_average(); // CTF defocus average (angstrom)
31 if ( ctf.defocus_deviation() ) def_dev = ctf.defocus_deviation(); // CTF defocus deviation (angstrom)
32 if ( ctf.astigmatism_angle() ) ast_ang = ctf.astigmatism_angle(); // CTF astigmatism angle (radians)
33 if ( ctf.baseline_type() ) { // Baseline equation
34 bt = ctf.baseline_type();
35 for ( i=0; i<NCTFPARAM; i++ ) base[i] = ctf.baseline(i);
36 }
37 if ( ctf.envelope_type() ) { // Envelope equation
38 et = ctf.envelope_type();
39 for ( i=0; i<NCTFPARAM; i++ ) env[i] = ctf.envelope(i);
40 }
41
42 update_terms();
43 zero(1);
44
45 return 0;
46 }
47
67 vector<double> CTFparam::calculate(int nrad, int npsi, double step_size)
68 {
69 vector<double> ctf;
70
71 if ( check_defocus() || check_Cs() ) {
72 cerr << "in CTFparam::calculate" << endl;
73 return ctf;
74 }
75
76 if ( npsi < 1 ) npsi = 1;
77
78 int i, j, k;
79 double s2, dphi, defocus;
80 double dpsi = M_PI*2.0/npsi;
81
82 ctf.resize(nrad*npsi);
83
84 defocus = def_avg;
85 for ( j=k=0; j<npsi; j++ ) {
86 if ( npsi > 1 ) defocus = def_avg + def_dev*cos(2*(j*dpsi-ast_ang));
87 for ( i=0; i<nrad; i++, k++ ) {
88 s2 = i*step_size;
89 s2 *= s2;
90 dphi = (t1*s2 - t2*defocus)*s2 - ac;
91 ctf[k] = sin(dphi);
92 // cout << k << tab << ctf[i] << endl;
93 }
94 }
95
96 zero(1);
97
98 return ctf;
99 }
100
115 vector<double> CTFparam::zeroes(double max_s)
116 {
117 vector<double> zero;
118
119 if ( check_defocus() || check_Cs() ) {
120 cerr << "in CTFparam::zeroes" << endl;
121 return zero;
122 }
123
124 long i;
125 double t, sm2(max_s*max_s);
126 double l = lambda();
127 double l3Cs = l*l*l*cs/2.0;
128 double fz = def_avg/(l*l*cs), fz2 = fz*fz;
129 double ps = ac/M_PI;
130
131 // cout << l*def_avg*sm2 << tab << l3Cs*sm2*sm2 << tab << ps << endl;
132
133 long nzero = (long) (l*def_avg*sm2 - l3Cs*sm2*sm2 + ps);
134
135 if ( nzero < 1 ) nzero = 1;
136
137 if ( verbose & VERB_DEBUG )
138 cout << "DEBUG CTFparam::zeroes: " << nzero << tab << max_s << endl;
139
140 zero.resize(nzero);
141
142 for ( i=0; i<nzero; i++ ) {
143 t = (i+1.0-ps)/l3Cs;
144 if ( fz2 > t )
145 zero[i] = sqrt(fz - sqrt(fz2 - t));
146 else
147 zero[i] = -1;
148 if ( !isfinite(zero[i]) ) zero[i] = 0.0001;
149 }
150
151 if ( verbose & VERB_DEBUG )
152 for ( i=0; i<nzero; i++ ) cout << i+1 << tab << zero[i] << tab << 1.0/zero[i] << endl;
153
154 return zero;
155 }
156
165 Bstring CTFparam::baseline_equation()
166 {
167 if ( base[0] <= 0 && base[1] == 0 ) base[0] = 1; // Default baseline
168
169 Bstring bleq(base[0], "%.4g");
170
171 switch ( bt ) {
172 case 1: // Polynomial
173 case 4: // Polynomial
174 bleq += Bstring(base[1], " + %.4g*$s") + Bstring(base[2], " + %.4g*$s2")
175 + Bstring(base[3], " + %.4g*$s3") + Bstring(base[4], " + %.4g*$s4");
176 break;
177 case 2: // Double gaussian
178 case 5: // Double gaussian
179 bleq += Bstring(base[1], " + %.4g") + Bstring(base[2], "*exp(%.4g*$s2)")
180 + Bstring(base[3], " + %.4g") + Bstring(base[4], "*exp(%.4g*$s2)");
181 break;
182 case 3: // EMAN style
183 case 6: // EMAN style
184 bleq += Bstring(base[1], " + %.4g") + Bstring(base[2], "*exp(%.4g*sqrt($s)")
185 + Bstring(base[3], " + %.4g*$s2)");
186 break;
187 default: break;
188 }
189
190 // for ( int i=5; i<8; ++i ) cout << tab << base[i];
191 // cout << endl;
192
193 if ( bt > 3 )
194 bleq += Bstring(base[5], " + %.4g") + Bstring(base[7], "*exp(%.4g")
195 + Bstring(base[6], "*(%.4g - $s)") + Bstring(base[6], "*(%.4g - $s))");
196
197 // cout << bleq << endl;
198
199 return bleq;
200 }
201
209 Bstring CTFparam::envelope_equation()
210 {
211 Bstring enveq(env[0], "%.4g");
212
213 switch ( et ) {
214 case 1: // Single gaussian
215 enveq += Bstring(env[1], "*exp(%.4g*$s2)");
216 break;
217 case 2: // Single gaussian with constant
218 enveq += Bstring(env[1], " + %.4g") + Bstring(env[2], "*exp(%.4g*$s2)");
219 break;
220 case 3: // Double gaussian
221 enveq += Bstring(env[1], "*exp(%.4g*$s2)") +
222 Bstring(env[2], " + %.4g") + Bstring(env[3], "*exp(%.4g*$s2)");
223 break;
224 case 4: // Double gaussian with constant
225 enveq += Bstring(env[1], " + %.4g") + Bstring(env[2], "*exp(%.4g*$s2)") +
226 Bstring(env[3], " + %.4g") + Bstring(env[4], "*exp(%.4g*$s2)");
227 break;
228 default: break;
229 }
230
231 return enveq;
232 }
233
242 int CTFparam::parse_baseline_equation(Bstring base_eq)
243 {
244 base_eq = base_eq.remove('\"');
245
246 int n(0);
247
248 if ( base_eq.contains("s4") ) { // Polynomial
249 bt = 1;
250 sscanf(base_eq.c_str(), "%lf + %lf*$s + %lf*$s2 + %lf*$s3 + %lf*$s4%n",
251 &base[0], &base[1], &base[2], &base[3], &base[4], &n);
252 } else if ( base_eq.contains("sqrt") ) { // EMAN style
253 bt = 3;
254 sscanf(base_eq.c_str(), "%lf + %lf*exp(%lf*sqrt($s) + %lf*$s2)%n",
255 &base[0], &base[1], &base[2], &base[3], &n);
256 } else if ( base_eq.contains("exp") ) { // Double gaussian
257 bt = 2;
258 sscanf(base_eq.c_str(), "%lf + %lf*exp(%lf*$s2) + %lf*exp(%lf*$s2)%n",
259 &base[0], &base[1], &base[2], &base[3], &base[4], &n);
260 }
261
262 char* ptr = &base_eq[n];
263 if ( strstr(ptr, "exp") ) {
264 // cout << ptr << endl;
265 sscanf(ptr, " + %lf*exp(%lf*(%lf - $s)*(%lf - $s))",
266 &base[5], &base[7], &base[6], &base[6]);
267 bt += 3;
268 // cout << base[5] << tab << base[6] << tab << base[7] << endl;
269 }
270
271 if ( verbose & VERB_DEBUG )
272 cout << "DEBUG parse_baseline_equation: bt=" << bt << " baseline=" <<
273 base[0] << "," << base[1] << "," << base[2] << "," <<
274 base[3] << "," << base[4] << endl;
275
276 return bt;
277 }
278
287 int CTFparam::parse_envelope_equation(Bstring env_eq)
288 {
289 env_eq = env_eq.remove('\"');
290
291 et = env_eq.count('+') + env_eq.count('s');
292
293 switch ( et ) {
294 case 1: // Single gaussian
295 sscanf(env_eq.c_str(), "%lf*exp(%lf*$s2)",
296 &env[0], &env[1]);
297 break;
298 case 2: // Single gaussian with constant
299 sscanf(env_eq.c_str(), "%lf + %lf*exp(%lf*$s2)",
300 &env[0], &env[1], &env[2]);
301 break;
302 case 3: // Double gaussian
303 sscanf(env_eq.c_str(), "%lf*exp(%lf*$s2) + %lf*exp(%lf*$s2)",
304 &env[0], &env[1], &env[2], &env[3]);
305 break;
306 case 4: // Double gaussian with constant
307 sscanf(env_eq.c_str(), "%lf + %lf*exp(%lf*$s2) + %lf*exp(%lf*$s2)",
308 &env[0], &env[1], &env[2], &env[3], &env[4]);
309 break;
310 default: break;
311 }
312
313 // if ( env[0] <= 0 ) env[0] = 1; // Default envelope
314 // if ( env[1] >= 0 ) env[1] = -10;
315 // if ( env[2] <= 0 ) env[2] = 0;
316 // if ( env[3] >= 0 ) env[3] = -10;
317
318 return 0;
319 }
320
338 vector<double> CTFparam::envelope_partial_coherence(long n, double freq_step)
339 {
340 long i;
341 double l = lambda(), Csl2(cs*l*l);
342 double s, arg, pal(M_PI*a);
343 vector<double> curve(n);
344
345 for ( i=0; i<n; i++ ) {
346 s = i*freq_step;
347 arg = pal*(Csl2*s*s - def_avg)*s;
348 curve[i] = exp(-arg*arg);
349 }
350
351 return curve;
352 }
353
372 vector<double> CTFparam::envelope_energy_spread(long n, double freq_step)
373 {
374 long i;
375 double s, arg;
376 // double fac(1.0/(16*log(2.0)));
377 double fac(0.5);
378 double l = lambda(), deccl(M_PI*l*cc*de/av);
379 vector<double> curve(n);
380
381 for ( i=0; i<n; i++ ) {
382 s = i*freq_step;
383 arg = deccl*s*s;
384 curve[i] = exp(-fac*arg*arg);
385 }
386
387 return curve;
388 }
389
403 double electron_wavelength(double volt)
404 {
405 if ( volt < 1 ) {
406 error_show("Error in electron_wavelength", __FILE__, __LINE__);
407 cerr << "The acceleration voltage is below 1 V! (" << volt << " V)" << endl;
408 return -1;
409 }
410
411 // return 12.2642596/sqrt(volt*(1+volt*0.978475598e-6));
412
413 return 1e10*PLANCK/sqrt(2*EMASS*ECHARGE*volt*(1+ECHARGE*volt/(2*EMASS*LIGHTSPEED*LIGHTSPEED)));
414 }
415
426 double beta2(double volt)
427 {
428 double f, b2(0);
429
430 f = 1 + ECHARGE*volt/(EMASS*LIGHTSPEED*LIGHTSPEED);
431
432 b2 = 1 - 1/(f*f);
433
434 return b2;
435 }
436
447 double beta(double volt)
448 {
449 return sqrt(beta2(volt));
450 }
451
452
462 vector<double> C_curve(long n, double freq_step)
463 {
464 long i;
465 double s2;
466 vector<double> curve(n);
467
468 for ( i=0; i<n; i++ ) {
469 s2 = i*freq_step;
470 s2 *= s2;
471 curve[i] = 0.893*exp(-0.2465*s2) + 0.2563*exp(-1.7100*s2) +
472 0.7570*exp(-6.4094*s2) + 1.0487*exp(-18.6113*s2) +
473 0.3575*exp(-50.2523*s2);
474 }
475
476 return curve;
477 }
478
479
480
CTFparam::zero
double zero(int i)
Definition: ctf.h:218
CTFparam::Cs
double Cs()
Definition: ctf.h:87
CTFparam::baseline_type
long baseline_type()
Definition: ctf.h:106
CTFparam::dE
double dE()
Definition: ctf.h:93
beta
double beta(double volt)
Calculates the relative electron velocity.
Definition: ctf.cpp:447
C_curve
vector< double > C_curve(long n, double freq_step)
Calculates the carbon scattering curve.
Definition: ctf.cpp:462
utilities.h
Header file for general utilities.
CTFparam::astigmatism_angle
double astigmatism_angle()
Definition: ctf.h:104
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
EMASS
#define EMASS
Definition: utilities.h:50
CTFparam::update
int update(CTFparam *ctf)
Definition: ctf.h:77
ECHARGE
#define ECHARGE
Definition: utilities.h:49
Bstring::remove
Bstring remove(const char c)
Definition: Bstring.cpp:465
CTFparam::envelope_energy_spread
vector< double > envelope_energy_spread(long n, double freq_step)
Calculates the envelope curve based on energy spread.
Definition: ctf.cpp:372
PLANCK
#define PLANCK
Definition: utilities.h:48
CTFparam::check_defocus
bool check_defocus()
Definition: ctf.h:123
Bstring::contains
bool contains(const Bstring &s)
Definition: Bstring.cpp:584
M_PI
#define M_PI
Definition: utilities.h:59
isfinite
bool isfinite(complex< T > &value)
electron_wavelength
double electron_wavelength(double volt)
Calculates the wavelength in angstrom from the acceleration voltage.
Definition: ctf.cpp:403
base
string base(string &filename)
Definition: string_util.cpp:28
CTFparam::check_Cs
bool check_Cs()
Definition: ctf.h:131
CTFparam::parse_baseline_equation
int parse_baseline_equation(Bstring base_eq)
Extracts the coefficients from the baseline string.
Definition: ctf.cpp:242
CTFparam::defocus_deviation
double defocus_deviation()
Definition: ctf.h:102
CTFparam::calculate
double calculate(double s2, double angle)
Definition: ctf.h:149
CTFparam::lambda
double lambda()
Definition: ctf.h:139
CTFparam::envelope_equation
Bstring envelope_equation()
Generates an envelope equation string from 4 coefficients.
Definition: ctf.cpp:209
beta2
double beta2(double volt)
Calculates the square of the relative electron velocity.
Definition: ctf.cpp:426
ctf.h
Header file for CTF (contrast transfer function) functions.
CTFparam::envelope_partial_coherence
vector< double > envelope_partial_coherence(long n, double freq_step)
Calculates the envelope curve based on partial coherence.
Definition: ctf.cpp:338
CTFparam::parse_envelope_equation
int parse_envelope_equation(Bstring env_eq)
Extracts the coefficients from the envelope string.
Definition: ctf.cpp:287
CTFparam::envelope_type
long envelope_type()
Definition: ctf.h:113
NCTFPARAM
#define NCTFPARAM
Definition: ctf.h:15
Bstring::c_str
const char * c_str()
Definition: Bstring.h:70
LIGHTSPEED
#define LIGHTSPEED
Definition: utilities.h:51
CTFparam::zeroes
vector< double > zeroes(double max_s)
Calculates the zeroes of a CTF curve on the spatial frequency scale.
Definition: ctf.cpp:115
Bstring
Definition: Bstring.h:29
CTFparam::volt
double volt()
Definition: ctf.h:83
Bstring::count
long count(const char c)
Definition: Bstring.cpp:269
CTFparam::baseline_equation
Bstring baseline_equation()
Generates a baseline equation string from 4 to 10 coefficients.
Definition: ctf.cpp:165
verbose
int verbose
CTFparam::defocus_average
double defocus_average()
Definition: ctf.h:100
CTFparam::baseline
vector< double > & baseline()
Definition: ctf.h:108
CTFparam::envelope
vector< double > & envelope()
Definition: ctf.h:115
CTFparam::amp_shift
double amp_shift()
Definition: ctf.h:95
CTFparam::Cc
double Cc()
Definition: ctf.h:89
error_show
int error_show(string message, string file, int line)
Displays the error with file and line reference.
Definition: utilities.cpp:755
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
CTFparam::alpha
double alpha()
Definition: ctf.h:91
CTFparam
Definition: ctf.h:26