Xmipp  v3.23.11-Nereus
ctf_estimate_from_psd_fast.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Javier Mota Garcia (jmota@cnb.csic.es)
4  * Carlos Oscar Sanchez Sorzano (coss@cnb.csic.es)
5  *
6  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21  * 02111-1307 USA
22  *
23  * All comments concerning this program package may be sent to the
24  * e-mail address 'xmipp@cnb.csic.es'
25  ***************************************************************************/
26 
27 #include <fstream>
28 #include <numeric>
29 #include "ctf_estimate_from_psd.h"
31 #include "data/numerical_tools.h"
32 #include "core/matrix2d.h"
33 #include "core/xmipp_fftw.h"
34 #include "core/metadata_vec.h"
35 
36 /* prototypes */
37 double CTF_fitness_fast(double *, void *);
38 extern double CTF_fitness(double *p, void *vprm);
39 
40 /* Number of CTF parameters */
41 constexpr int ALL_CTF_PARAMETERS2D = 38;
42 constexpr int ALL_CTF_PARAMETERS = 28;
43 constexpr int CTF_PARAMETERS = 20;
44 constexpr int PARAMETRIC_CTF_PARAMETERS = 16;
45 constexpr int BACKGROUND_CTF_PARAMETERS = 9;
46 constexpr int SQRT_CTF_PARAMETERS = 6;
47 constexpr int ENVELOPE_PARAMETERS = 11;
48 constexpr int DEFOCUS_PARAMETERS = 3;
49 constexpr int FIRST_SQRT_PARAMETER = 14;
50 constexpr int FIRST_ENVELOPE_PARAMETER = 2;
51 constexpr int FIRST_DEFOCUS_PARAMETER = 0;
52 
53 //#define DEBUG_WITH_TEXTFILES
54 #ifdef DEBUG_WITH_TEXTFILES
55 std::ofstream fhDebug;
56 #define DEBUG_OPEN_TEXTFILE(fnRoot) fhDebug.open((fnRoot+"_debug.txt").c_str());
57 #define DEBUG_TEXTFILE(str) fhDebug << time (NULL) << " " << str << std::endl;
58 #define DEBUG_MODEL_TEXTFILE fhDebug << global_ctfmodel << std::endl;
59 #else
60 #define DEBUG_OPEN_TEXTFILE(fnRoot);
61 #define DEBUG_TEXTFILE(str);
62 #define DEBUG_MODEL_TEXTFILE
63 #endif
64 
65 
66 namespace AdjustCTF1D
67 {
69 }
70 
71 using namespace AdjustCTF1D;
72 
73 #define ASSIGN_CTF_PARAM(index, paramName) if (ia <= index && l > 0) { ctf1Dmodel.paramName = p[index]; --l; }
74 
75 /* Assign ctf1Dmodel from a vector and viceversa ----------------------------- */
77  int l)
78 {
79  ctf1Dmodel.Tm = Tm;
80 
81  ASSIGN_CTF_PARAM(0, Defocus);
82  ASSIGN_CTF_PARAM(1, kV);
83  ASSIGN_CTF_PARAM(2, K);
84  ASSIGN_CTF_PARAM(3, Cs);
85  ASSIGN_CTF_PARAM(4, Ca);
86  ASSIGN_CTF_PARAM(5, espr);
87  ASSIGN_CTF_PARAM(6, ispr); //deltaI/I
88  ASSIGN_CTF_PARAM(7, alpha);
89  ASSIGN_CTF_PARAM(8, DeltaF);
90  ASSIGN_CTF_PARAM(9, DeltaR);
91  ASSIGN_CTF_PARAM(10, envR0);
92  ASSIGN_CTF_PARAM(11, envR1);
93  ASSIGN_CTF_PARAM(12, envR2);
94  ASSIGN_CTF_PARAM(13, Q0);
95  ASSIGN_CTF_PARAM(14, base_line);
96  ASSIGN_CTF_PARAM(15, sqrt_K);
97  ASSIGN_CTF_PARAM(16, sq);
98  ASSIGN_CTF_PARAM(17, bgR1);
99  ASSIGN_CTF_PARAM(18, bgR2);
100  ASSIGN_CTF_PARAM(19, bgR3);
101  ASSIGN_CTF_PARAM(20, gaussian_K);
102  ASSIGN_CTF_PARAM(21, sigma1);
103  ASSIGN_CTF_PARAM(22, Gc1);
104  ASSIGN_CTF_PARAM(23, gaussian_K2);
105  ASSIGN_CTF_PARAM(24, sigma2);
106  ASSIGN_CTF_PARAM(25, Gc2);
107  ASSIGN_CTF_PARAM(26, phase_shift);
108  ASSIGN_CTF_PARAM(27, VPP_radius);
109 
110 }//function assignCTFfromParameters
111 
112 #define ASSIGN_PARAM_CTF(index, paramName) if (ia <= index && l > 0) { p[index] = ctf1Dmodel.paramName; --l; }
113 
115  int l)
116 {
117 
118  ASSIGN_PARAM_CTF(0, Defocus);
119  ASSIGN_PARAM_CTF(1, kV);
120  ASSIGN_PARAM_CTF(2, K);
121  ASSIGN_PARAM_CTF(3, Cs);
122  ASSIGN_PARAM_CTF(4, Ca);
123  ASSIGN_PARAM_CTF(5, espr);
124  ASSIGN_PARAM_CTF(6, ispr); //deltaI/I
125  ASSIGN_PARAM_CTF(7, alpha);
126  ASSIGN_PARAM_CTF(8, DeltaF);
127  ASSIGN_PARAM_CTF(9, DeltaR);
128  ASSIGN_PARAM_CTF(10, envR0);
129  ASSIGN_PARAM_CTF(11, envR1);
130  ASSIGN_PARAM_CTF(12, envR2);
131  ASSIGN_PARAM_CTF(13, Q0);
132  ASSIGN_PARAM_CTF(14, base_line);
133  ASSIGN_PARAM_CTF(15, sqrt_K);
134  ASSIGN_PARAM_CTF(16, sq);
135  ASSIGN_PARAM_CTF(17, bgR1);
136  ASSIGN_PARAM_CTF(18, bgR2);
137  ASSIGN_PARAM_CTF(19, bgR3);
138  ASSIGN_PARAM_CTF(20, gaussian_K);
139  ASSIGN_PARAM_CTF(21, sigma1);
140  ASSIGN_PARAM_CTF(22, Gc1);
141  ASSIGN_PARAM_CTF(23, gaussian_K2);
142  ASSIGN_PARAM_CTF(24, sigma2);
143  ASSIGN_PARAM_CTF(25, Gc2);
144  ASSIGN_PARAM_CTF(26, phase_shift);
145  ASSIGN_PARAM_CTF(27, VPP_radius);
146 
147 }
148 
149 #define COPY_ctfmodel_TO_CURRENT_GUESS \
150  global_prm->assignParametersFromCTF_fast(global_prm->current_ctfmodel, \
151  MATRIX1D_ARRAY(*global_prm->adjust_params),0,ALL_CTF_PARAMETERS);
152 
153 
154 /* Read parameters --------------------------------------------------------- */
156 {
158 
159  initial_ctfmodel.enable_CTF = initial_ctfmodel.enable_CTFnoise = true;
160  initial_ctfmodel.readParams(program);
161  initial_ctfmodel2D.readParams(program);
162 
163  if (initial_ctfmodel.Defocus>100e3)
164  REPORT_ERROR(ERR_ARG_INCORRECT,"Defocus cannot be larger than 10 microns (100,000 Angstroms)");
165  Tm = initial_ctfmodel.Tm;
166 }
167 
169 {
170  fn_psd = getParam("--psd");
171  readBasicParams(this);
172 }
173 
174 /* Usage ------------------------------------------------------------------- */
176 {
178 }
179 
181 {
182  defineBasicParams(this);
184 }
185 
186 /* Produce side information ------------------------------------------------ */
188 {
189  adjust.resize(ALL_CTF_PARAMETERS);
190  adjust.initZeros();
191  current_ctfmodel.clear();
192  ctfmodel_defoci.clear();
193  assignParametersFromCTF_fast(initial_ctfmodel, MATRIX1D_ARRAY(adjust), 0, ALL_CTF_PARAMETERS);
194  // Read the CTF file, supposed to be the uncentered squared amplitudes
195  if (fn_psd != "")
196  ctftomodel.read(fn_psd);
197  f = &(ctftomodel());
198 
200  current_ctfmodel.precomputeValues(x_contfreq);
201 }
202 
204 {
205  Matrix1D<int> idx(1); // Indexes for Fourier plane
206  Matrix1D<double> freq(1); // Frequencies for Fourier plane
207 
208  assignCTFfromParameters_fast(MATRIX1D_ARRAY(*adjust_params), current_ctfmodel,
209  0, ALL_CTF_PARAMETERS);
210  current_ctfmodel.produceSideInfo();
211 
212  I.initZeros(psd_exp_radial);
214  {
215  XX(idx) = i;
216  FFT_idx2digfreq(*f, idx, freq);
217  double w=freq.module();
218  if (w>max_freq_psd)
219  continue;
220  digfreq2contfreq(freq, freq, Tm);
221  // Decide what to save
222  current_ctfmodel.precomputeValues(XX(freq));
223  if (action <= 1)
224  I(i) = current_ctfmodel.getValueNoiseAt();
225  else if (action == 2)
226  {
227  double E = current_ctfmodel.getValueDampingAt();
228  I(i) = current_ctfmodel.getValueNoiseAt() + E * E;
229 
230  }
231  else if (action >= 3 && action <= 6)
232  {
233  double ctf = current_ctfmodel.getValuePureAt();
234  I(i) = current_ctfmodel.getValueNoiseAt() + ctf * ctf;
235  }
236  else
237  {
238  double ctf = current_ctfmodel.getValuePureAt();
239  I(i) = ctf;
240  }
241  if (apply_log)
242  I(i) = 10 * log10(I(i));
243 
244  }
245 }
246 
247 void ProgCTFEstimateFromPSDFast::saveIntermediateResults_fast(const FileName &fn_root, bool generate_profiles = true)
248 {
249  std::ofstream plot_radial;
251  generateModelSoFar_fast(save, false);
252  if (!generate_profiles)
253  return;
254  plot_radial.open((fn_root + "_radial.txt").c_str());
255  if (!plot_radial)
256  REPORT_ERROR(
258  "save_intermediate_results::Cannot open plot file for writing\n");
259 
260  //plot_radial << "# freq_dig freq_angstrom model psd enhanced logModel logPsd\n";
261 
262  // Generate radial average
263  MultidimArray<double> radial_CTFmodel_avg;
264  radial_CTFmodel_avg.initZeros(psd_exp_enhanced_radial);
265 
266  FOR_ALL_ELEMENTS_IN_ARRAY1D(w_digfreq)
267  {
268  if (mask(i) <= 0)
269  continue;
270  double model2 = save(i);
271 
272  int r = w_digfreq_r(i);
273  radial_CTFmodel_avg(r) = model2;
274 
275  plot_radial << w_digfreq(r, 0) << " " << w_contfreq(r, 0)
276  << " " << radial_CTFmodel_avg(r) << " "
277  << psd_exp_enhanced_radial(r) << " " << psd_exp_radial(r)
278  << " " << log10(radial_CTFmodel_avg(r)) << " "
279  << std::endl;
280  }
281 
282  plot_radial.close();
283 }
284 
285 /* CTF fitness ------------------------------------------------------------- */
286 /* This function measures the distance between the estimated CTF and the
287  measured CTF */
289 {
290  double retval;
291 
292  // Generate CTF model
293  switch (action)
294  {
295  // Remind that p is a vector whose first element is at index 1
296  case 0:
297  assignCTFfromParameters_fast(p - FIRST_SQRT_PARAMETER + 1,
298  current_ctfmodel, FIRST_SQRT_PARAMETER, SQRT_CTF_PARAMETERS);
299 
300  if (show_inf >= 2)
301  {
302  std::cout << "Input vector:";
303  for (int i = 1; i <= SQRT_CTF_PARAMETERS; i++)
304  std::cout << p[i] << " ";
305  std::cout << std::endl;
306  }
307  break;
308  case 1:
309  assignCTFfromParameters_fast(p - FIRST_SQRT_PARAMETER + 1,
310  current_ctfmodel, FIRST_SQRT_PARAMETER,
312  if (show_inf >= 2)
313  {
314  std::cout << "Input vector:";
315  for (int i = 1; i <= BACKGROUND_CTF_PARAMETERS; i++)
316  std::cout << p[i] << " ";
317  std::cout << std::endl;
318  }
319  break;
320  case 2:
321  assignCTFfromParameters_fast(p - FIRST_ENVELOPE_PARAMETER + 1,
322  current_ctfmodel, FIRST_ENVELOPE_PARAMETER, ENVELOPE_PARAMETERS);
323  if (show_inf >= 2)
324  {
325  std::cout << "Input vector:";
326  for (int i = 1; i <= ENVELOPE_PARAMETERS; i++)
327  std::cout << p[i] << " ";
328  std::cout << std::endl;
329  }
330  break;
331  case 3:
332  assignCTFfromParameters_fast(p - FIRST_DEFOCUS_PARAMETER + 1,
333  current_ctfmodel, FIRST_DEFOCUS_PARAMETER, DEFOCUS_PARAMETERS);
334  psd_theo_radial_derivative.initZeros();
335  if (show_inf >= 2)
336  {
337  std::cout << "Input vector:";
338  for (int i = 1; i <= DEFOCUS_PARAMETERS; i++)
339  std::cout << p[i] << " ";
340  std::cout << std::endl;
341  }
342  break;
343  case 4:
344  assignCTFfromParameters_fast(p - 0 + 1, current_ctfmodel, 0,
346  psd_theo_radial.initZeros();
347  if (show_inf >= 2)
348  {
349  std::cout << "Input vector:";
350  for (int i = 1; i <= CTF_PARAMETERS; i++)
351  std::cout << p[i] << " ";
352  std::cout << std::endl;
353  }
354  break;
355  case 5:
356  case 6:
357  case 7:
358  assignCTFfromParameters_fast(p - 0 + 1, current_ctfmodel, 0,
360  psd_theo_radial.initZeros();
361  if (show_inf >= 2)
362  {
363  std::cout << "Input vector:";
364  for (int i = 1; i <= ALL_CTF_PARAMETERS; i++)
365  std::cout << p[i] << " ";
366  std::cout << std::endl;
367  }
368  break;
369  }
370 
371  current_ctfmodel.produceSideInfo();
372  if (show_inf >= 2)
373  std::cout << "Model:\n" << current_ctfmodel << std::endl;
374  if (!current_ctfmodel.hasPhysicalMeaning())
375  {
376  if (show_inf >= 2)
377  std::cout << "Does not have physical meaning\n";
378  return heavy_penalization;
379  }
380  if (action > 3
381  && (fabs((current_ctfmodel.Defocus - ctfmodel_defoci.Defocus)
382  / ctfmodel_defoci.Defocus) > 0.2) && !noDefocusEstimate)
383  {
384  if (show_inf >= 2)
385  std::cout << "Too large defocus\n";
386  return heavy_penalization;
387  }
388  if (initial_ctfmodel.Defocus != 0 && action >= 3 && !selfEstimation && !noDefocusEstimate)
389  {
390  // If there is an initial model, the true solution
391  // cannot be too far
392  if (fabs(initial_ctfmodel.Defocus - current_ctfmodel.Defocus) > defocus_range)
393  {
394  if (show_inf >= 2)
395  {
396  std::cout << "Too far from hint: Initial (" << initial_ctfmodel.Defocus << ")"
397  << " current guess (" << current_ctfmodel.Defocus << ") max allowed difference: "
398  << defocus_range << std::endl;
399  }
400  return heavy_penalization;
401 
402 
403  }
404  }
405  if ((initial_ctfmodel.phase_shift != 0.0 || initial_ctfmodel.phase_shift != 1.57079) && action >= 5)
406  {
407  if (fabs(initial_ctfmodel.phase_shift - current_ctfmodel.phase_shift) > 0.26)
408  {
409  return heavy_penalization;
410  }
411  }
412  // Now the 1D error
413  double distsum = 0;
414  int N = 0, Ncorr = 0;
415  double enhanced_avg = 0;
416  double model_avg = 0;
417  double enhanced_model = 0;
418  double enhanced2 = 0;
419  double model2 = 0;
420  double lowerLimit = 1.1 * min_freq_psd;
421  double upperLimit = 0.9 * max_freq_psd;
422  const MultidimArray<double>& local_enhanced_ctf = psd_exp_enhanced_radial;
423  int XdimW=XSIZE(w_digfreq);
424  corr13=0;
425  FOR_ALL_ELEMENTS_IN_ARRAY1D(w_digfreq)
426  {
427  if (DIRECT_A1D_ELEM(mask, i) <= 0)
428  continue;
429 
430  // Compute each component
431  current_ctfmodel.precomputeValues(i);
432  double bg = current_ctfmodel.getValueNoiseAt();
433 
434  double envelope=0, ctf_without_damping, ctf_with_damping=0, current_envelope = 0;
435  double ctf2_th=0;
436  double ctf2 = DIRECT_A1D_ELEM(psd_exp_radial, i);
437  double dist = 0;
438  double ctf_with_damping2;
439  switch (action)
440  {
441  case 0:
442  case 1:
443  ctf2_th = bg;
444  dist = fabs(ctf2 - bg);
445  if (penalize && bg > ctf2 && DIRECT_A1D_ELEM(w_digfreq, i) > max_gauss_freq)
446  dist *= current_penalty;
447  break;
448  case 2:
449  envelope = current_ctfmodel.getValueDampingAt();
450  ctf2_th = bg + envelope * envelope;
451  dist = fabs(ctf2 - ctf2_th);
452  if (penalize && ctf2_th < ctf2 && DIRECT_A1D_ELEM(w_digfreq, i) > max_gauss_freq)
453  dist *= current_penalty;
454  break;
455  case 3:
456  case 4:
457  case 5:
458  case 6:
459  case 7:
460  envelope = current_ctfmodel.getValueDampingAt();
461  ctf_without_damping = current_ctfmodel.getValuePureWithoutDampingAt();
462 
463  ctf_with_damping = envelope * ctf_without_damping;
464  ctf2_th = bg + ctf_with_damping * ctf_with_damping;
465 
466  if (DIRECT_A1D_ELEM(w_digfreq,i) < upperLimit
467  && DIRECT_A1D_ELEM(w_digfreq,i) > lowerLimit)
468  {
469  if (action == 3 ||
470  (action == 4 && DIRECT_A1D_ELEM(mask_between_zeroes,i) == 1) ||
471  (action == 7 && DIRECT_A1D_ELEM(mask_between_zeroes,i) == 1))
472  {
473  double enhanced_ctf = DIRECT_A1D_ELEM(local_enhanced_ctf, i);
474  ctf_with_damping2 = ctf_with_damping * ctf_with_damping;
475  enhanced_model += enhanced_ctf * ctf_with_damping2;
476  enhanced2 += enhanced_ctf * enhanced_ctf;
477  model2 += ctf_with_damping2 * ctf_with_damping2;
478  enhanced_avg += enhanced_ctf;
479  model_avg += ctf_with_damping2;
480  Ncorr++;
481  if (action==3)
482  {
483  int r = A1D_ELEM(w_digfreq_r,i);
484  A1D_ELEM(psd_theo_radial,r) = ctf2_th;
485  }
486  }
487  }
488  if (envelope > 1e-2)
489  dist = fabs(ctf2 - ctf2_th) / (envelope * envelope);
490  else
491  dist = fabs(ctf2 - ctf2_th);
492  // This expression comes from mapping any value so that
493  // bg becomes 0, and bg+envelope^2 becomes 1
494  // This is the transformation
495  // (x-bg) x-bg
496  // -------------=-------
497  // (bg+env^2-bg) env^2
498  // If we subtract two of this scaled values
499  // x-bg y-bg x-y
500  // ------- - ------- = -------
501  // env^2 env^2 env^2
502  break;
503 
504  }
505 
506  distsum += dist * DIRECT_A1D_ELEM(mask,i);
507  N++;
508  }
509  if (N > 0)
510  { retval = distsum/N ;
511  }
512  else
513  retval = heavy_penalization;
514  if (show_inf >=2)
515  std::cout << "Fitness1=" << retval << std::endl;
516  if ( (((action >= 3) && (action <= 4)) || (action == 7))
517  && (Ncorr > 0) && (enhanced_weight != 0) )
518  {
519 
520  model_avg /= Ncorr;
521  enhanced_avg /= Ncorr;
522  double correlation_coeff = enhanced_model/Ncorr - model_avg * enhanced_avg;
523  double sigma1 = sqrt(fabs(enhanced2/Ncorr - enhanced_avg * enhanced_avg));
524  double sigma2 = sqrt(fabs(model2/Ncorr - model_avg * model_avg));
525  double maxSigma = std::max(sigma1, sigma2);
526  if (sigma1 < XMIPP_EQUAL_ACCURACY || sigma2 < XMIPP_EQUAL_ACCURACY
527  || (fabs(sigma1 - sigma2) / maxSigma > 0.9 && action>=5))
528  {
529  retval = heavy_penalization;
530  if (show_inf>=2)
531  std::cout << "Fitness2=" << heavy_penalization << " sigma1=" << sigma1 << " sigma2=" << sigma2 << std::endl;
532  }
533  else
534  {
535  correlation_coeff /= sigma1 * sigma2;
536  if (action == 7)
537  corr13 = correlation_coeff;
538  else
539  retval -= enhanced_weight * correlation_coeff;
540  if (show_inf >= 2)
541  {
542  std::cout << "model_avg=" << model_avg << std::endl;
543  std::cout << "enhanced_avg=" << enhanced_avg << std::endl;
544  std::cout << "enhanced_model=" << enhanced_model / Ncorr
545  << std::endl;
546  std::cout << "sigma1=" << sigma1 << std::endl;
547  std::cout << "sigma2=" << sigma2 << std::endl;
548  std::cout << "Fitness2="
549  << -(enhanced_weight * correlation_coeff)
550  << " (" << correlation_coeff << ")" << std::endl;
551  }
552  }
553 
554  // Correlation of the derivative of the radial profile
555  if (action==3 || evaluation_reduction==1)
556  {
557  int state=0;
558  double maxDiff=0;
559  psd_theo_radial_derivative.initZeros();
560  double lowerlimt=1.1*min_freq;
561  double upperlimit=0.9*max_freq;
562  FOR_ALL_ELEMENTS_IN_ARRAY1D(psd_theo_radial)
563  if (A1D_ELEM(w_digfreq_r_iN,i)>0)
564  {
565  double freq=A1D_ELEM(w_digfreq,i);
566  switch (state)
567  {
568  case 0:
569  if (freq>lowerlimt)
570  state=1;
571  break;
572  case 1:
573  if (freq>upperlimit)
574  state=2;
575  else
576  {
577  double diff=A1D_ELEM(psd_theo_radial,i)-A1D_ELEM(psd_theo_radial,i-1);
578 
579  A1D_ELEM(psd_theo_radial_derivative,i)=diff;
580  maxDiff=std::max(maxDiff,fabs(diff));
581  }
582  break;
583  }
584  }
585  double corrRadialDerivative=0,mux=0, muy=0, Ncorr=0, sigmax=0, sigmay=0;
586  double iMaxDiff=1.0/maxDiff;
587 
588  FOR_ALL_ELEMENTS_IN_ARRAY1D(psd_theo_radial)
589  {
590  A1D_ELEM(psd_theo_radial_derivative,i)*=iMaxDiff;
591  double x=A1D_ELEM(psd_exp_enhanced_radial_derivative,i);
592  double y=A1D_ELEM(psd_theo_radial_derivative,i);
593  corrRadialDerivative+=x*y;
594  mux+=x;
595  muy+=y;
596  sigmax+=x*x;
597  sigmay+=y*y;
598  Ncorr++;
599  }
600 
601  if (Ncorr>0)
602  {
603  double iNcorr=1.0/Ncorr;
604  corrRadialDerivative*=iNcorr;
605  mux*=iNcorr;
606  muy*=iNcorr;
607  sigmax=sqrt(fabs(sigmax*iNcorr-mux*mux));
608  sigmay=sqrt(fabs(sigmay*iNcorr-muy*muy));
609  corrRadialDerivative=(corrRadialDerivative-mux*muy)/(sigmax*sigmay);
610 
611  }
612  retval-=corrRadialDerivative;
613  if (show_inf>=2)
614  {
615  std::cout << "Fitness3=" << -corrRadialDerivative << std::endl;
616  if (show_inf==3)
617  {
618  psd_exp_enhanced_radial.write("PPPexpRadial_fast.txt");
619  psd_theo_radial.write("PPPtheoRadial.txt");
620  psd_exp_enhanced_radial_derivative.write("PPPexpRadialDerivative_fast.txt");
621  psd_theo_radial_derivative.write("PPPtheoRadialDerivative.txt");
622  }
623  }
624  }
625  }
626 
627  return retval;
628 }
629 
630 double CTF_fitness_fast(double *p, void *vprm)
631 {
632  auto *prm=(ProgCTFEstimateFromPSDFast *) vprm;
633  return prm->CTF_fitness_object_fast(p);
634 }
635 
636 /* Center focus ----------------------------------------------------------- */
637 void ProgCTFEstimateFromPSDFast::center_optimization_focus_fast(bool adjust_th, double margin = 1)
638 {
639  if (show_optimization)
640  std::cout << "Freq frame before focusing=" << min_freq_psd << ","
641  << max_freq_psd << std::endl << "Value_th before focusing="
642  << value_th << std::endl;
643 
644  double w1 = min_freq_psd, w2 = max_freq_psd;
645 
646  // Compute maximum value within central region
647  if (adjust_th)
648  {
650  generateModelSoFar_fast(save, false);
651  double max_val = 0;
652  FOR_ALL_ELEMENTS_IN_ARRAY1D(w_digfreq)
653  {
654  double w = w_digfreq(i);
655  if (w >= w1 && w <= w2)
656  max_val = XMIPP_MAX(max_val, save(i));
657  }
658  if (value_th != -1)
659  value_th = XMIPP_MIN(value_th, max_val * margin);
660  else
661  value_th = max_val * margin;
662  }
663 
664 
665  if (show_optimization)
666  std::cout << "Freq frame after focusing=" << min_freq_psd << ","
667  << max_freq_psd << std::endl << "Value_th after focusing="
668  << value_th << std::endl;
669 }
670 // Estimate sqrt parameters ------------------------------------------------
671 // Results are written in current_ctfmodel
673 {
674  if (show_optimization)
675  std::cout << "Computing first sqrt background ...\n";
676 
677  // Estimate the base line taking the value of the CTF
678  // for the maximum X
679  double base_line = 0;
680  int N = 0;
681  FOR_ALL_ELEMENTS_IN_ARRAY1D(w_digfreq)
682  if (w_digfreq(i) > 0.4)
683  {
684  N++;
685  base_line += psd_exp_radial(i);
686  }
687  if (0 == N) {
688  REPORT_ERROR(ERR_NUMERICAL, "N is zero (0), which would lead to division by zero");
689  }
690  current_ctfmodel.base_line = base_line / N;
691 
692  // Find the linear least squares solution for the sqrt part
693  Matrix2D<double> A(2, 2);
694  A.initZeros();
695  Matrix1D<double> b(2);
696  b.initZeros();
697 
698  FOR_ALL_ELEMENTS_IN_ARRAY1D(w_digfreq)
699  {
700  if (mask(i) <= 0)
701  continue;
702 
703  // Compute weight for this point
704  double weight = 1 + max_freq_psd - w_digfreq(i);
705 
706  // Compute error
707  current_ctfmodel.precomputeValues(x_contfreq(i));
708  double explained = current_ctfmodel.getValueNoiseAt();
709  double unexplained = psd_exp_radial(i) - explained;
710  if (unexplained <= 0)
711  continue;
712  unexplained = log(unexplained);
713 
714  double X = -sqrt(w_contfreq(i));
715  A(0, 0) += weight * X * X;
716  A(0, 1) += weight * X;
717  A(1, 1) += weight * 1;
718  b(0) += X * weight * unexplained;
719  b(1) += weight * unexplained;
720 
721  }
722  A(1, 0) = A(0, 1);
723  b = A.inv() * b;
724 
725  current_ctfmodel.sq = b(0);
726  current_ctfmodel.sqrt_K = exp(b(1));
728 
729  if (show_optimization)
730  {
731  std::cout << "First SQRT Fit:\n" << current_ctfmodel << std::endl;
732  saveIntermediateResults_fast("step01a_first_sqrt_fit_fast", true);
733  }
734 
735  // Now optimize .........................................................
736  double fitness;
739  steps.initConstant(1);
740 
741  // Optimize without penalization
742  if (show_optimization)
743  std::cout << "Looking for best fitting sqrt ...\n";
744  penalize = false;
745  int iter;
746  powellOptimizer(*adjust_params, FIRST_SQRT_PARAMETER + 1,
747  SQRT_CTF_PARAMETERS, CTF_fitness_fast, global_prm, 0.05, fitness, iter, steps,
748  show_optimization);
749 
750  // Optimize with penalization
751  if (show_optimization)
752  std::cout << "Penalizing best fitting sqrt ...\n";
753  penalize = true;
754  current_penalty = 2;
755  int imax = CEIL(log(penalty) / log(2.0));
756 
757  for (int i = 1; i <= imax; i++)
758  {
759  if (show_optimization)
760  std::cout << " Iteration " << i << " penalty="
761  << current_penalty << std::endl;
762  powellOptimizer(*adjust_params, FIRST_SQRT_PARAMETER + 1,
763  SQRT_CTF_PARAMETERS, CTF_fitness_fast, global_prm, 0.05, fitness, iter,
764  steps, show_optimization);
765  current_penalty *= 2;
766  current_penalty =
767  XMIPP_MIN(current_penalty, penalty);
768  }
769  // Keep the result in adjust
770  current_ctfmodel.forcePhysicalMeaning();
772 
773  if (show_optimization)
774  {
775  std::cout << "Best penalized SQRT Fit:\n" << current_ctfmodel
776  << std::endl;
777  saveIntermediateResults_fast("step01b_best_penalized_sqrt_fit_fast", true);
778  }
779 
780  center_optimization_focus_fast(true, 1.5);
781 
782 }
783 
784 // Estimate gaussian parameters --------------------------------------------
785 //#define DEBUG
787 {
788 
789  if (show_optimization)
790  std::cout << "Computing first background Gaussian parameters ...\n";
791 
792  // Compute radial averages
793  MultidimArray<double> radial_CTFmodel_avg(YSIZE(*f) / 2);
794  MultidimArray<double> radial_CTFampl_avg(YSIZE(*f) / 2);
795  MultidimArray<int> radial_N(YSIZE(*f) / 2);
796  double w_max_gauss = 0.25;
797 
798  FOR_ALL_ELEMENTS_IN_ARRAY1D(w_digfreq)
799  {
800  if (mask(i) <= 0)
801  continue;
802  double w = w_digfreq(i);
803 
804  if (w > w_max_gauss)
805  continue;
806 
807  int r = FLOOR(w * (double)YSIZE(*f));
808 
809  current_ctfmodel.precomputeValues(x_contfreq(i));
810  radial_CTFmodel_avg(r) += current_ctfmodel.getValueNoiseAt();
811  radial_CTFampl_avg(r) += psd_exp_radial(i);
812  radial_N(r)++;
813 
814  }
815  // Compute the average radial error
816  double error2_avg = 0;
817  int N_avg = 0;
819  error.initZeros(radial_CTFmodel_avg);
820  FOR_ALL_ELEMENTS_IN_ARRAY1D(radial_CTFmodel_avg)
821  {
822  if (radial_N(i) == 0)
823  continue;
824  error(i) = (radial_CTFampl_avg(i) - radial_CTFmodel_avg(i))
825  / radial_N(i);
826  error2_avg += error(i) * error(i);
827  N_avg++;
828  }
829  if (N_avg != 0)
830  error2_avg /= N_avg;
831 
832 #ifdef DEBUG
833 
834  std::cout << "Error2 avg=" << error2_avg << std::endl;
835 #endif
836 
837  // Compute the minimum radial error
838  bool first = true, OK_to_proceed = false;
839  double error2_min = 0, wmin=0;
840  FOR_ALL_ELEMENTS_IN_ARRAY1D(radial_CTFmodel_avg)
841  {
842  if (radial_N(i) == 0)
843  continue;
844 
845  double w = w_digfreq(i);
846 
847  if (error(i) < 0 && first){
848  continue;
849  }
850 
851  else if (error(i) < 0)
852  {
853  break;
854  }
855 
856  double error2 = error(i) * error(i);
857  // If the two lines cross, do not consider any error until
858  // the cross is "old" enough
859  if (first && error2 > 0.15 * error2_avg)
860  OK_to_proceed = true;
861  if (first && i > 0)
862  OK_to_proceed &= (error(i) < error(i - 1));
863 
864  // If the error now is bigger than a 30% (1.69=1.3*1.3) of the error min
865  // this must be a rebound. Stop here
866  if (!first && error2 > 1.69 * error2_min)
867  break;
868  if (first && OK_to_proceed)
869  {
870  wmin = w;
871  error2_min = error2;
872  first = false;
873  }
874  if (!first && error2 < error2_min)
875  {
876  wmin = w;
877  error2_min = error2;
878  }
879 #ifdef DEBUG
880  std::cout << w << " " << error2 << " " << wmin << " " << std::endl;
881 #endif
882 
883  }
884 
885  // Compute the frequency of the minimum error
886  max_gauss_freq = wmin;
887 #ifdef DEBUG
888 
889  std::cout << "Freq of the minimum error: " << wmin << " " << fmin << std::endl;
890 #endif
891 
892  // Compute the maximum radial error
893  first = true;
894  double error2_max = 0, wmax=0, fmax;
895  FOR_ALL_ELEMENTS_IN_ARRAY1D(radial_CTFmodel_avg)
896  {
897  if (radial_N(i) == 0)
898  continue;
899  double w = w_digfreq(i);
900  if (w > wmin)
901  continue;
902 
903  if (error(i) < 0 && first)
904  continue;
905  else if (error(i) < 0)
906  break;
907  double error2 = error(i) * error(i);
908  if (first)
909  {
910  wmax = w;
911  error2_max = error2;
912  first = false;
913  }
914  if (error2 > error2_max)
915  {
916  wmax = w;
917  error2_max = error2;
918  }
919 #ifdef DEBUG
920  std::cout << w << " " << error2 << " " << wmax << std::endl;
921 #endif
922 
923  }
924  fmax = current_ctfmodel.Gc1 = wmax / Tm;
925 #ifdef DEBUG
926 
927  std::cout << "Freq of the maximum error: " << wmax << " " << fmax << std::endl;
928 #endif
929 
930  // Find the linear least squares solution for the gauss part
931  Matrix2D<double> A(2, 2);
932  A.initZeros();
933  Matrix1D<double> b(2);
934  b.initZeros();
935 
936 
937  FOR_ALL_ELEMENTS_IN_ARRAY1D(w_digfreq)
938  {
939 
940  if (mask(i) <= 0)
941  continue;
942 
943  if (w_digfreq(i) > wmin)
944  continue;
945 
946  double fmod = w_contfreq(i);
947 
948  // Compute weight for this point
949  double weight = 1 + max_freq_psd - w_digfreq(i);
950 
951  // Compute error
952  current_ctfmodel.precomputeValues(x_contfreq(i));
953  double explained = current_ctfmodel.getValueNoiseAt();
954  double unexplained = psd_exp_radial(i) - explained;
955  if (unexplained <= 0)
956  continue;
957  unexplained = log(unexplained);
958  double F = -(fmod - fmax) * (fmod - fmax);
959 
960  A(0, 0) += weight * 1;
961  A(0, 1) += weight * F;
962  A(1, 1) += weight * F * F;
963  b(0) += weight * unexplained;
964  b(1) += F * weight * unexplained;
965 
966  }
967  A(1, 0) = A(0, 1);
968 
969  if ( (A(0, 0)== 0) && (A(1, 0)== 0) && (A(1, 1)== 0))
970  {
971  std::cout << "Matrix A is zeros" << std::endl;
972  }
973  else
974  {
975 
976  b = A.inv() * b;
977  current_ctfmodel.sigma1 = XMIPP_MIN(fabs(b(1)), 95e3); // This value should beconformant with the physical
978  // meaning routine in CTF.cc
979  current_ctfmodel.gaussian_K = exp(b(0));
980  // Store the CTF values in adjust
981  current_ctfmodel.forcePhysicalMeaning();
983 
984  if (show_optimization)
985  {
986  std::cout << "First Background Fit:\n" << current_ctfmodel << std::endl;
987  saveIntermediateResults_fast("step01c_first_background_fit_fast", true);
988  }
989  center_optimization_focus_fast(true, 1.5);
990 
991  }
992 }
993 
994 // Estimate envelope parameters --------------------------------------------
995 //#define DEBUG
997 {
998  if (show_optimization)
999  std::cout << "Looking for best fitting envelope ...\n";
1000 
1001  // Set the envelope
1002  current_ctfmodel.Ca = initial_ctfmodel.Ca;
1003  current_ctfmodel.K = 1.0;
1004  current_ctfmodel.espr = 0.0;
1005  current_ctfmodel.ispr = 0.0;
1006  current_ctfmodel.alpha = 0.0;
1007  current_ctfmodel.DeltaF = 0.0;
1008  current_ctfmodel.DeltaR = 0.0;
1009  current_ctfmodel.Q0 = initial_ctfmodel.Q0;
1010  current_ctfmodel.envR0 = 0.0;
1011  current_ctfmodel.envR1 = 0.0;
1013 
1014  // Now optimize the envelope
1015  penalize = false;
1016  int iter;
1017  double fitness;
1019  steps.resize(ENVELOPE_PARAMETERS);
1020  steps.initConstant(1);
1021 
1022  steps(1) = 0; // Do not optimize Cs
1023  steps(5) = 0; // Do not optimize for alpha, since Ealpha depends on the defocus
1024 
1025  if (modelSimplification >= 1)
1026  steps(6) = steps(7) = 0; // Do not optimize DeltaF and DeltaR
1027  powellOptimizer(*adjust_params, FIRST_ENVELOPE_PARAMETER + 1,
1028  ENVELOPE_PARAMETERS, CTF_fitness_fast, global_prm, 0.05, fitness, iter, steps,
1029  show_optimization);
1030 
1031  // Keep the result in adjust
1032  current_ctfmodel.forcePhysicalMeaning();
1034 
1035  if (show_optimization)
1036  {
1037  std::cout << "Best envelope Fit:\n" << current_ctfmodel << std::endl;
1038  saveIntermediateResults_fast("step02a_best_envelope_fit_fast", true);
1039  }
1040 
1041  // Optimize with penalization
1042  if (show_optimization)
1043  std::cout << "Penalizing best fitting envelope ...\n";
1044  penalize = true;
1045  current_penalty = 2;
1046  int imax = CEIL(log(penalty) / log(2.0));
1047  for (int i = 1; i <= imax; i++)
1048  {
1049  if (show_optimization)
1050  std::cout << " Iteration " << i << " penalty="
1051  << current_penalty << std::endl;
1052  powellOptimizer(*adjust_params, FIRST_ENVELOPE_PARAMETER + 1,
1053  ENVELOPE_PARAMETERS, CTF_fitness_fast, global_prm, 0.05, fitness, iter,
1054  steps, show_optimization);
1055  current_penalty *= 2;
1056  current_penalty =
1057  XMIPP_MIN(current_penalty, penalty);
1058  }
1059  // Keep the result in adjust
1060  current_ctfmodel.forcePhysicalMeaning();
1062 
1063  if (show_optimization)
1064  {
1065  std::cout << "Best envelope Fit:\n" << current_ctfmodel << std::endl;
1066  saveIntermediateResults_fast("step02b_best_penalized_envelope_fit_fast", true);
1067  }
1068 
1069 }
1070 
1071 // Estimate defoci ---------------------------------------------------------
1072 //#define DEBUG
1073 #define OUTLIERS
1074 //#define FILTER
1076 {
1077  double fitness;
1078  int iter;
1080  steps.initConstant(1);
1081  steps(1) = 0; // Do not optimize kV
1082  steps(2) = 0; // Do not optimize K
1083  if(!selfEstimation)
1084  {
1085  (*adjust_params)(0) = initial_ctfmodel.Defocus;
1086  (*adjust_params)(2) = current_ctfmodel.K;
1087  powellOptimizer(*adjust_params, FIRST_DEFOCUS_PARAMETER + 1,
1089  fitness, iter, steps, false);
1090  }
1091  else
1092  {
1093  /*
1094  * Defocus estimation s^2 stigmator
1095  *
1096  * CTF = sin(PI*lambda*defocus*R^2)
1097  * CTF = sin(PI*lambda*defocus*w^2/Ts^2)
1098  * w^2 = omega
1099  * omega = 2*K0/Xdim K0: position of the maximum of the psd in fourier
1100  *
1101  * Defocus = 2*K0*(2*Ts)^2/lambda
1102  */
1103  MultidimArray<double> psd_exp_radial2;
1104  MultidimArray<double> background;
1105  MultidimArray<double> psd_background;
1106  action = 1;
1107  generateModelSoFar_fast(background, false);
1108  action = 3;
1109  psd_background.initZeros(background);
1110 
1111 #ifdef DEBUG
1112  std::cout << "background\n" << background << std::endl;
1113  std::cout << "--------------------------------------" << std::endl;
1114 
1115  std::cout << "psd_exp_radial\n" << psd_exp_radial << std::endl;
1116  std::cout << "--------------------------------------" << std::endl;
1117 #endif
1118 
1119  FOR_ALL_ELEMENTS_IN_ARRAY1D(background)
1120  {
1121  if(w_digfreq(i)>min_freq && w_digfreq(i)<max_freq)
1122  psd_background(i)= background(i)-psd_exp_radial(i);
1123  }
1124 
1125  //Uncomment to apply a high-pass FILTER to psd_background
1126 #ifdef FILTER
1127  double alpha = 0.1;
1128  Matrix1D<double> A_coeff(2);
1129  VEC_ELEM(A_coeff,0) = 1;
1130  VEC_ELEM(A_coeff,1) = alpha-1;
1131  Matrix1D<double> B_coeff(2);
1132  VEC_ELEM(B_coeff,0) = 1-alpha;
1133  VEC_ELEM(B_coeff,1) = alpha-1;
1134  MultidimArray<double> psd_background_filter;
1135  MultidimArray<double> aux_filter;
1136  psd_background_filter.initZeros(psd_background);
1137  aux_filter.initZeros(psd_background);
1138  matlab_filter(B_coeff,A_coeff,psd_background,psd_background_filter,aux_filter);
1139  psd_background = psd_background_filter;
1140 #endif
1141 
1142 #ifdef DEBUG
1143  std::cout << "psdbackground\n" << psd_background << std::endl;
1144  std::cout << "--------------------------------------" << std::endl;
1145 #endif
1146  psd_exp_radial2.initZeros(psd_exp_radial);
1147 
1148  double deltaW=1.0/(2*XSIZE(w_digfreq)*current_ctfmodel.Tm);
1149  double deltaW2=1.0/(XSIZE(w_digfreq)*pow(2*current_ctfmodel.Tm,2));
1150  FOR_ALL_ELEMENTS_IN_ARRAY1D(psd_exp_radial2)
1151  {
1152  double w2=i*deltaW2;
1153  double w=sqrt(w2);
1154  double widx=w/deltaW;
1155  size_t lowerIdx=floor(widx);
1156  double weight=widx-floor(widx);
1157  if(i < XSIZE(psd_exp_radial2)-1)
1158  {
1159  double value =(1-weight)*A1D_ELEM(psd_background,lowerIdx)
1160  +weight*A1D_ELEM(psd_background,lowerIdx+1);
1161 
1162  A1D_ELEM(psd_exp_radial2,i) = value*value;
1163  }
1164  }
1165 #ifdef DEBUG
1166  std::cout << "psd_exp_radial2\n" << psd_exp_radial2 << std::endl;
1167  std::cout << "--------------------------------------" << std::endl;
1168 #endif
1169  FourierTransformer FourierPSD;
1170  FourierPSD.FourierTransform(psd_exp_radial2, psd_fft, false);
1171 
1172  const double minDefocus=2000;
1173  int startIndex = ceil(std::max((double)7,minDefocus*current_ctfmodel.lambda/(2*pow(2*current_ctfmodel.Tm,2))));
1174 #ifdef DEBUG
1175  std::cout << "Start index=" << minDefocus*current_ctfmodel.lambda/(2*pow(2*current_ctfmodel.Tm,2)) << std::endl;
1176  std::cout << "--------------------------------------" << std::endl;
1177 #endif
1178  if (current_ctfmodel.VPP_radius != 0.0)
1179  startIndex = 10; //avoid low frequencies
1181  {
1182  if(i>=startIndex) {
1183  amplitud.push_back(abs(psd_fft[i]));
1184 #ifdef DEBUG
1185  std::cout << abs(psd_fft[i]) << std::endl;
1186 #endif
1187  }
1188  }
1189 #ifdef DEBUG
1190  std::cout << "--------------------------------------" << std::endl;
1191 #endif
1192 
1193  //Uncomment to remove outliers from amplitud
1194 #ifdef OUTLIERS
1195  double totalSum = std::accumulate(amplitud.begin(), amplitud.end(), 0.0);
1196 
1197  double amplitudMean = totalSum / amplitud.size();
1198  double sdSum = 0;
1199  for(double i : amplitud)
1200  {
1201  double diff=amplitud[i]-amplitudMean;
1202  sdSum += diff*diff;
1203  }
1204  double amplitudSD = sqrt(sdSum/amplitud.size());
1205  double differenceSD = 3*amplitudSD;
1206  for(double i : amplitud)
1207  {
1208  if (amplitud[i]>amplitudMean+differenceSD){
1209  amplitud[i] = amplitudMean+differenceSD;
1210  }
1211  }
1212 #endif
1213 
1214  double maxValue=-1e38;
1215  int finalIndex=-1;
1216 #ifdef DEBUG
1217  std::cout << "Looking for maximum ...\n";
1218 #endif
1219  for (size_t i=1; i<amplitud.size()-1; i++)
1220  {
1221 #ifdef DEBUG
1222  std::cout << "i=" << i << " amplitude i= " << amplitud[i] << std::endl;
1223 #endif
1224  if (amplitud[i]>maxValue && amplitud[i]>=amplitud[i+1])
1225  {
1226  maxValue=amplitud[i];
1227  finalIndex=i;
1228 #ifdef DEBUG
1229  std::cout << "New maximum " << i << " maxValue=" << maxValue << std::endl;
1230 #endif
1231  }
1232  }
1233 
1234  //double maxValue = *max_element(amplitud.begin(),amplitud.end());
1235  //int finalIndex = distance(amplitud.begin(),max_element(amplitud.begin(),amplitud.end()));
1236  current_ctfmodel.Defocus = (floor(finalIndex+startIndex+1)*pow(2*current_ctfmodel.Tm,2))/
1237  current_ctfmodel.lambda;
1238 
1239 #ifdef DEBUG
1240  std::cout << "maxValue: " << maxValue << std::endl;
1241  std::cout << "finalIndex: " << finalIndex << std::endl;
1242  std::cout << "defocus: " << current_ctfmodel.Defocus << std::endl;
1243 #endif
1244  }
1245  // Keep the result in adjust
1246  current_ctfmodel.forcePhysicalMeaning();
1248  ctfmodel_defoci = current_ctfmodel;
1249 
1250  if (show_optimization)
1251  {
1252  std::cout << "First defocus Fit:\n" << ctfmodel_defoci << std::endl;
1253  saveIntermediateResults_fast("step03a_first_defocus_fit_fast", true);
1254  }
1255 }
1256 #undef DEBUG
1257 #undef FILTER
1258 #undef OUTLIERS
1259 
1260 // Estimate second gaussian parameters -------------------------------------
1261 //#define DEBUG
1263 {
1264  if (show_optimization)
1265  std::cout << "Computing first background Gaussian2 parameters ...\n";
1266 
1267  // Compute radial averages
1268  MultidimArray<double> radial_CTFmodel_avg(YSIZE(*f) / 2);
1269  MultidimArray<double> radial_CTFampl_avg(YSIZE(*f) / 2);
1270  MultidimArray<int> radial_N(YSIZE(*f) / 2);
1271  double w_max_gauss = 0.25;
1272  FOR_ALL_ELEMENTS_IN_ARRAY1D(w_digfreq)
1273  {
1274  if (mask(i) <= 0)
1275  continue;
1276  double w = w_digfreq(i);
1277  if (w > w_max_gauss)
1278  continue;
1279 
1280  int r = FLOOR(w * (double)YSIZE(*f));
1281  double f_x = DIRECT_A1D_ELEM(x_contfreq, i);
1282  current_ctfmodel.precomputeValues(f_x);
1283  double bg = current_ctfmodel.getValueNoiseAt();
1284  double envelope = current_ctfmodel.getValueDampingAt();
1285  double ctf_without_damping =
1286  current_ctfmodel.getValuePureWithoutDampingAt();
1287  double ctf_with_damping = envelope * ctf_without_damping;
1288  double ctf2_th = bg + ctf_with_damping * ctf_with_damping;
1289  radial_CTFmodel_avg(r) += ctf2_th;
1290  radial_CTFampl_avg(r) += psd_exp_radial(i);
1291  radial_N(r)++;
1292  }
1293 
1294  // Compute the average radial error
1296  error.initZeros(radial_CTFmodel_avg);
1297  FOR_ALL_ELEMENTS_IN_ARRAY1D(radial_CTFmodel_avg)
1298  {
1299  if (radial_N(i) == 0)
1300  continue;
1301  error(i) = (radial_CTFampl_avg(i) - radial_CTFmodel_avg(i))/ radial_N(i);
1302  }
1303 #ifdef DEBUG
1304  std::cout << "Error:\n" << error << std::endl;
1305 #endif
1306 
1307  // Compute the frequency of the minimum error
1308  double wmin = 0.15;
1309 
1310  // Compute the maximum (negative) radial error
1311  double error_max = 0, wmax=0, fmax;
1312  FOR_ALL_ELEMENTS_IN_ARRAY1D(radial_CTFmodel_avg)
1313  {
1314  if (radial_N(i) == 0)
1315  continue;
1316  double w = w_digfreq(i);
1317  if (w > wmin)
1318  break;
1319  if (error(i) < error_max)
1320  {
1321  wmax = w;
1322  error_max = error(i);
1323  }
1324  }
1325  fmax = current_ctfmodel.Gc2 = wmax / Tm;
1326 #ifdef DEBUG
1327 
1328  std::cout << "Freq of the maximum error: " << wmax << " " << fmax << std::endl;
1329 #endif
1330 
1331  // Find the linear least squares solution for the gauss part
1332  Matrix2D<double> A(2, 2);
1333  A.initZeros();
1334  Matrix1D<double> b(2);
1335  b.initZeros();
1336  int N = 0;
1337 
1338  FOR_ALL_ELEMENTS_IN_ARRAY1D(w_digfreq)
1339  {
1340  if (mask(i) <= 0)
1341  continue;
1342  if (w_digfreq(i) > wmin)
1343  continue;
1344  double fmod = w_contfreq(i);
1345 
1346  // Compute the zero on the direction of this point
1347  Matrix1D<double> u(1), fzero(1);
1348  u = x_contfreq(i) / fmod;
1349  current_ctfmodel.lookFor(1, u, fzero, 0);
1350  if (fmod > fzero.module())
1351  continue;
1352 
1353  // Compute weight for this point
1354  double weight = 1 + max_freq_psd - w_digfreq(i);
1355  // Compute error
1356  double f_x = DIRECT_A1D_ELEM(x_contfreq, i);
1357  current_ctfmodel.precomputeValues(f_x);
1358  double bg = current_ctfmodel.getValueNoiseAt();
1359  double envelope = current_ctfmodel.getValueDampingAt();
1360  double ctf_without_damping =
1361  current_ctfmodel.getValuePureWithoutDampingAt();
1362  double ctf_with_damping = envelope * ctf_without_damping;
1363  double ctf2_th = bg + ctf_with_damping * ctf_with_damping;
1364  double explained = ctf2_th;
1365  double unexplained = explained - psd_exp_radial(i);
1366  if (unexplained <= 0)
1367  continue;
1368  unexplained = log(unexplained);
1369  double F = -(fmod - fmax) * (fmod - fmax);
1370  A(0, 0) += weight * 1;
1371  A(0, 1) += weight * F;
1372  A(1, 1) += weight * F * F;
1373  b(0) += weight * unexplained;
1374  b(1) += F * weight * unexplained;
1375  N++;
1376  }
1377 
1378  if (N != 0)
1379  {
1380  A(1, 0) = A(0, 1);
1381 
1382  double det=A.det();
1383  if (fabs(det)>1e-9)
1384  {
1385  b = A.inv() * b;
1386  current_ctfmodel.sigma2 = XMIPP_MIN(fabs(b(1)), 95e3); // This value should be conformant with the physical
1387  // meaning routine in CTF.cc
1388  current_ctfmodel.gaussian_K2 = exp(b(0));
1389  }
1390  else
1391  {
1392  current_ctfmodel.sigma2 = 0;
1393  current_ctfmodel.gaussian_K2 = 0;
1394  }
1395  }
1396  else
1397  {
1398  current_ctfmodel.sigma2 = 0;
1399  current_ctfmodel.gaussian_K2 = 0;
1400  }
1401 
1402  // Store the CTF values in adjust
1403  current_ctfmodel.forcePhysicalMeaning();
1405 
1406  if (show_optimization)
1407  {
1408  std::cout << "First Background Gaussian 2 Fit:\n" << current_ctfmodel
1409  << std::endl;
1410  saveIntermediateResults_fast("step04a_first_background2_fit_fast", true);
1411  }
1412 }
1413 #undef DEBUG
1414 
1415 /* Main routine ------------------------------------------------------------ */
1416 //#define DEBUG
1417 double ROUT_Adjust_CTFFast(ProgCTFEstimateFromPSDFast &prm, CTFDescription1D &output_ctfmodel, bool standalone)
1418 {
1420  global_prm = &prm;
1421  if (standalone || prm.show_optimization)
1422  prm.show();
1423  prm.produceSideInfo();
1424  DEBUG_TEXTFILE(formatString("After producing side info: Avg=%f",prm.ctftomodel().computeAvg()));
1426  // Build initial frequency mask
1427  prm.value_th = -1;
1428  prm.min_freq_psd = prm.min_freq;
1429  prm.max_freq_psd = prm.max_freq;
1430 
1431  // Set some global variables
1432  prm.adjust_params = &prm.adjust;
1433  prm.penalize = false;
1434  prm.max_gauss_freq = 0;
1435  prm.heavy_penalization = prm.f->computeMax() * YSIZE(*prm.f);
1436  prm.show_inf = 0;
1437 
1438  // Some variables needed by all steps
1439  int iter;
1440  double fitness;
1442  /************************************************************************/
1443  /* STEPs 1, 2, 3 and 4: Find background which best fits the CTF */
1444  /************************************************************************/
1445  prm.current_ctfmodel.enable_CTFnoise = true;
1446  prm.current_ctfmodel.enable_CTF = false;
1447  prm.evaluation_reduction = 4;
1448 
1449  // If initial parameters were not supplied for the gaussian curve,
1450  // estimate them from the CTF file
1451  prm.action = 0;
1452  if (prm.adjust(FIRST_SQRT_PARAMETER) == 0)
1453  {
1456  }
1457 
1458  // Optimize the current background
1459  prm.action = 1;
1460  prm.penalize = true;
1461  prm.current_penalty = prm.penalty;
1463  steps.initConstant(1);
1464  if (!prm.modelSimplification >= 3)
1465  steps(1) = steps(2) = steps(4) = 0;
1467  BACKGROUND_CTF_PARAMETERS, CTF_fitness_fast, global_prm, 0.01, fitness, iter,
1468  steps, prm.show_optimization);
1469 
1470  // Make sure that the model has physical meaning
1471  // (In some machines due to numerical imprecission this check is necessary
1472  // at the end)
1475 
1476  if (prm.show_optimization)
1477  {
1478  std::cout << "Best background Fit:\n" << prm.current_ctfmodel << std::endl;
1479  prm.saveIntermediateResults_fast("step01d_best_background_fit_fast", true);
1480  }
1481 
1482  DEBUG_TEXTFILE(formatString("Step 4: CTF_fitness=%f",CTF_fitness_fast));
1484 
1485  /************************************************************************/
1486  /* STEPs 5 and 6: Find envelope which best fits the CTF */
1487  /************************************************************************/
1488 
1489  prm.action = 2;
1490  prm.current_ctfmodel.enable_CTF = true;
1491 
1496 
1497  if (prm.initial_ctfmodel.Q0 != 0)
1500 
1501  if (prm.show_optimization)
1502  {
1503  std::cout << "Best envelope Fit:\n" << prm.current_ctfmodel << std::endl;
1504  prm.saveIntermediateResults_fast("step02b_best_penalized_envelope_fit_fast", true);
1505  }
1506 
1507  DEBUG_TEXTFILE(formatString("Step 6: espr=%f",prm.current_ctfmodel.espr));
1509 
1510  /************************************************************************/
1511  /* STEP 7: defocus and angular parameters */
1512  /************************************************************************/
1513  prm.action = 3;
1514  if (!prm.noDefocusEstimate)
1515  prm.estimate_defoci_fast();
1516  else
1518  DEBUG_TEXTFILE(formatString("Step 7: Defocus=%f",prm.current_ctfmodel.Defocus));
1520  /************************************************************************/
1521  /* STEPs 9, 10 and 11: all parameters included second Gaussian */
1522  /************************************************************************/
1523  prm.action = 5;
1524  if (prm.modelSimplification < 2)
1526 
1527  steps.resize(ALL_CTF_PARAMETERS);
1528  steps.initConstant(1);
1529  steps(1) = 0; // kV
1530  steps(3) = 0; // The spherical aberration (Cs) is not optimized
1531  steps(27) = 0; //VPP radius not optimized
1532  if (prm.noDefocusEstimate)
1533  steps(0)=0; // Defocus
1534  if (prm.initial_ctfmodel.Q0 != 0)
1535  steps(13) = 0; // Q0
1536  if (prm.modelSimplification >= 1)
1537  steps(8) = steps(9) = 0;
1538  if (prm.initial_ctfmodel.VPP_radius == 0)
1539  steps(26) = 0; //VPP phase shift
1540 
1542  global_prm, 0.01, fitness, iter, steps, prm.show_optimization);
1543 
1546 
1547  if (prm.show_optimization)
1548  {
1549  std::cout << "Best fit with Gaussian2:\n" << prm.current_ctfmodel
1550  << std::endl;
1551  prm.saveIntermediateResults_fast("step04b_best_fit_with_gaussian2_fast", true);
1552  }
1553 
1554  /************************************************************************/
1555  /* STEP 12: 2D estimation parameters */
1556  /************************************************************************/
1558  auto *prm2D = new ProgCTFEstimateFromPSD(&prm);
1559  if (prm.noDefocusEstimate)
1560  {
1561  prm2D->current_ctfmodel.DeltafU=prm.initial_ctfmodel2D.DeltafU;
1562  prm2D->current_ctfmodel.DeltafV=prm.initial_ctfmodel2D.DeltafV;
1563  prm2D->current_ctfmodel.azimuthal_angle=prm.initial_ctfmodel2D.azimuthal_angle;
1564  prm2D->noDefocusEstimate=true;
1565  }
1566 
1568  steps.initConstant(1);
1569  steps(3) = 0; // kV
1570  steps(5) = 0; // The spherical aberration (Cs) is not optimized
1571  steps(37) = 0; //VPP radius not optimized
1572  if (prm.noDefocusEstimate)
1573  steps(0)=steps(1)=steps(2)=0; // Defocus and azimuthal angle
1574  if (prm2D->initial_ctfmodel.Q0 != 0)
1575  steps(15) = 0; // Q0
1576  if (prm2D->modelSimplification >= 3)
1577  steps(20) = steps(21) = steps(23) = 0;
1578  if (prm2D->modelSimplification >= 2)
1579  steps(24) = steps(25) = steps(26) = steps(27) = steps(28) = steps(29) = 0;
1580  if (prm2D->modelSimplification >= 1)
1581  steps(10) = steps(11) = 0;
1582  if(prm2D->initial_ctfmodel.VPP_radius == 0)
1583  steps(36) = 0;
1584 
1585  prm2D->adjust_params = prm.adjust_params;
1586  prm2D->adjust_params->initZeros();
1587  prm2D->assignParametersFromCTF(prm2D->current_ctfmodel,MATRIX1D_ARRAY(*prm2D->adjust_params),0, ALL_CTF_PARAMETERS2D, true);
1588 
1589  if (prm.refineAmplitudeContrast)
1590  steps(15) = 1; // Q0
1591  powellOptimizer(*prm2D->adjust_params, 0 + 1, ALL_CTF_PARAMETERS2D, CTF_fitness,
1592  prm2D, 0.01, fitness, iter, steps, prm2D->show_optimization);
1593 
1594  prm2D->current_ctfmodel.forcePhysicalMeaning();
1595 
1596  //We adopt that always DeltafU > DeltafV so if this is not the case we change the values and the angle
1597  if (!prm.noDefocusEstimate && prm2D->current_ctfmodel.DeltafV > prm2D->current_ctfmodel.DeltafU)
1598  {
1599  double temp;
1600  temp = prm2D->current_ctfmodel.DeltafU;
1601  prm2D->current_ctfmodel.DeltafU = prm2D->current_ctfmodel.DeltafV;
1602  prm2D->current_ctfmodel.DeltafV = temp;
1603  prm2D->current_ctfmodel.azimuthal_angle -= 90;
1604  }
1605  prm2D->assignParametersFromCTF(prm2D->current_ctfmodel,MATRIX1D_ARRAY(*prm2D->adjust_params),0, ALL_CTF_PARAMETERS2D, true);
1606  if (prm2D->show_optimization)
1607  {
1608  std::cout << "Best fit with 2D parameters:\n" << prm2D->current_ctfmodel << std::endl;
1609  prm2D->saveIntermediateResults("step05b_estimate_2D_parameters", true);
1610  }
1611 
1612  /************************************************************************/
1613  /* STEP 13: Produce output */
1614  /************************************************************************/
1615  prm2D->action = 7;
1616  if (prm2D->fn_psd != "")
1617  {
1618  // Define mask between first and third zero
1619  prm2D->mask_between_zeroes.initZeros(prm2D->mask);
1620  Matrix1D<double> u(2), z1(2), z3(2);
1621 #ifdef NEVERDEFINED
1622  FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(prm2D->mask_between_zeroes)
1623  {
1624  VECTOR_R2(u, DIRECT_MULTIDIM_ELEM(prm2D->x_digfreq, n), DIRECT_MULTIDIM_ELEM(prm2D->y_digfreq, n));
1625  u /= u.module();
1626  prm2D->current_ctfmodel.lookFor(3, u, z3, 0);
1627  if (DIRECT_MULTIDIM_ELEM(prm2D->w_contfreq, n) >= z3.module())
1628  continue;
1629  prm2D->current_ctfmodel.lookFor(1, u, z1, 0);
1630  if (z1.module() < DIRECT_MULTIDIM_ELEM(prm2D->w_contfreq, n))
1631  DIRECT_MULTIDIM_ELEM(prm2D->mask_between_zeroes, n) = 1;
1632 
1633  }
1634 #endif
1635  XX(u)=1; YY(u)=0;
1636  prm2D->current_ctfmodel.lookFor(3, u, z3, 0);
1637  prm2D->current_ctfmodel.lookFor(1, u, z1, 0);
1638  double z1m = z1.module();
1639  double z3m = z3.module();
1640  FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(prm2D->mask_between_zeroes)
1641  {
1642  double wn=DIRECT_MULTIDIM_ELEM(prm2D->w_contfreq, n);
1643  if (wn<=z3m && wn>=z1m)
1644  DIRECT_MULTIDIM_ELEM(prm2D->mask_between_zeroes, n) = 1;
1645  }
1646  // Evaluate the correlation in this region
1647  CTF_fitness(prm2D->adjust_params->adaptForNumericalRecipes(), prm2D);
1648  // Save results
1649  FileName fn_rootCTFPARAM = prm2D->fn_psd.withoutExtension();
1650 
1651  FileName fn_rootMODEL = fn_rootCTFPARAM;
1652  size_t atPosition=fn_rootCTFPARAM.find('@');
1653 
1654  if (atPosition!=std::string::npos)
1655  {
1656  fn_rootMODEL=formatString("%03d@%s",textToInteger(fn_rootCTFPARAM.substr(0, atPosition)),
1657  fn_rootCTFPARAM.substr(atPosition+1).c_str());
1658  fn_rootCTFPARAM=formatString("region%03d@%s",textToInteger(fn_rootCTFPARAM.substr(0, atPosition)),
1659  fn_rootCTFPARAM.substr(atPosition+1).c_str());
1660  }
1661  else
1662  fn_rootCTFPARAM=(String)"fullMicrograph@"+fn_rootCTFPARAM;
1663 
1664  prm2D->saveIntermediateResults(fn_rootMODEL, false);
1665  prm2D->current_ctfmodel.Tm /= prm2D->downsampleFactor;
1666  prm2D->current_ctfmodel.azimuthal_angle = std::fmod(prm2D->current_ctfmodel.azimuthal_angle,360.);
1667  prm2D->current_ctfmodel.phase_shift = (prm2D->current_ctfmodel.phase_shift*180)/3.14;
1668  if(prm2D->current_ctfmodel.phase_shift<0.0)
1669  prm2D->current_ctfmodel.phase_shift = 0.0;
1670 
1671  prm2D->current_ctfmodel.write(fn_rootCTFPARAM + ".ctfparam_tmp");
1672  MetaDataVec MD;
1673  MD.read(fn_rootCTFPARAM + ".ctfparam_tmp");
1674  size_t id = MD.firstRowId();
1675  MD.setValue(MDL_CTF_X0, (double)output_ctfmodel.x0*prm2D->Tm, id);
1676  MD.setValue(MDL_CTF_XF, (double)output_ctfmodel.xF*prm2D->Tm, id);
1677  MD.setValue(MDL_CTF_Y0, (double)output_ctfmodel.y0*prm2D->Tm, id);
1678  MD.setValue(MDL_CTF_YF, (double)output_ctfmodel.yF*prm2D->Tm, id);
1679  MD.setValue(MDL_CTF_CRIT_FITTINGSCORE, fitness, id);
1680  MD.setValue(MDL_CTF_CRIT_FITTINGCORR13, prm2D->corr13, id);
1682  MD.setValue(MDL_CTF_DOWNSAMPLE_PERFORMED, prm2D->downsampleFactor, id);
1683  MD.write(fn_rootCTFPARAM + ".ctfparam",MD_APPEND);
1684  fn_rootCTFPARAM = fn_rootCTFPARAM + ".ctfparam_tmp";
1685 
1686  fn_rootCTFPARAM.deleteFile();
1687  }
1688  output_ctfmodel = prm2D->current_ctfmodel;
1689  return fitness;
1690 }
1691 
1693 {
1694  CTFDescription1D ctf1Dmodel;
1695  ROUT_Adjust_CTFFast(*this, ctf1Dmodel);
1696 }
#define DEBUG_TEXTFILE(str)
#define VECTOR_R2(v, x, y)
Definition: matrix1d.h:112
The CTF is valid within (x0,y0) to (xF,yF) in the micrograph coordinates.
#define YSIZE(v)
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
#define XMIPP_MAX(x, y)
Definition: xmipp_macros.h:193
MultidimArray< double > * f
double module() const
Definition: matrix1d.h:983
Image< double > ctftomodel
CTF amplitude to model.
__host__ __device__ float2 floor(const float2 v)
FileName removeLastExtension() const
void center_optimization_focus_fast(bool adjust_th, double margin)
void read(const FileName &inFile, const std::vector< MDLabel > *desiredLabels=nullptr, bool decomposeStack=true) override
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
constexpr int FIRST_SQRT_PARAMETER
void sqrt(Image< double > &op)
constexpr int DEFOCUS_PARAMETERS
static double * y
Couldn&#39;t write to file.
Definition: xmipp_error.h:140
Matrix1D< double > * adjust_params
void readBasicParams(XmippProgram *program)
Read parameters.
double DeltafV
Defocus in V (in Angstroms). Negative values are underfocused.
Definition: ctf.h:830
void defineParams()
Define Parameters.
constexpr int CTF_PARAMETERS
#define A1D_ELEM(v, i)
void readBasicParams(XmippProgram *program)
Read parameters.
double Tm
Sampling rate.
double espr
Definition: ctf.h:251
void show()
Show parameters.
void inv(Matrix2D< T > &result) const
Definition: matrix2d.cpp:663
doublereal * w
double evaluateIceness(const MultidimArray< double > &enhanced_ctftomodel, double Tm)
void abs(Image< double > &op)
void write(const FileName &outFile, WriteModeMetaData mode=MD_OVERWRITE) const
double phase_shift
Definition: ctf.h:305
void powellOptimizer(Matrix1D< double > &p, int i0, int n, double(*f)(double *x, void *), void *prm, double ftol, double &fret, int &iter, const Matrix1D< double > &steps, bool show)
#define DEBUG_OPEN_TEXTFILE(fnRoot)
glob_prnt iter
The CTF is valid within (x0,y0) to (xF,yF) in the micrograph coordinates.
#define COPY_ctfmodel_TO_CURRENT_GUESS
void FFT_idx2digfreq(T &v, const Matrix1D< int > &idx, Matrix1D< double > &freq)
Definition: xmipp_fft.h:80
FileName fn_psd
CTF filename.
doublereal * x
#define i
constexpr int ENVELOPE_PARAMETERS
static void defineParams(XmippProgram *program)
Define parameters in the command line.
Definition: ctf.cpp:1287
constexpr int ALL_CTF_PARAMETERS2D
Correlation between the 1st and 3rd ring of the CTF.
double max_freq
Maximum frequency to adjust.
static constexpr double penalty
double DeltafU
Global gain. By default, 1.
Definition: ctf.h:828
bool enable_CTF
Enable CTF part.
Definition: ctf.h:275
#define DEBUG
double azimuthal_angle
Azimuthal angle (between X and U) in degrees.
Definition: ctf.h:832
glob_log first
#define DIRECT_A1D_ELEM(v, i)
Score of the fitting.
doublereal * b
#define ASSIGN_PARAM_CTF(index, paramName)
void produceSideInfo()
Produce side information.
#define FLOOR(x)
Definition: xmipp_macros.h:240
void log(Image< double > &op)
#define XX(v)
Definition: matrix1d.h:85
constexpr int FIRST_ENVELOPE_PARAMETER
double CTF_fitness_fast(double *, void *)
bool setValue(const MDObject &mdValueIn, size_t id)
#define CEIL(x)
Definition: xmipp_macros.h:225
double * f
double ROUT_Adjust_CTFFast(ProgCTFEstimateFromPSDFast &prm, CTFDescription1D &output_ctfmodel, bool standalone)
Incorrect argument received.
Definition: xmipp_error.h:113
size_t firstRowId() const override
bool noDefocusEstimate
No defocus estimate.
#define XMIPP_EQUAL_ACCURACY
Definition: xmipp_macros.h:119
void resize(size_t Xdim, bool copy=true)
Definition: matrix1d.h:410
constexpr int ALL_CTF_PARAMETERS
#define XSIZE(v)
T det() const
Definition: matrix2d.cpp:38
double CTF_fitness(double *p, void *vprm)
void max(Image< double > &op1, const Image< double > &op2)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
double Tm
Sampling rate (A/pixel)
Definition: ctf.h:240
bool refineAmplitudeContrast
Refine amplitude contrast.
Error related to numerical calculation.
Definition: xmipp_error.h:179
#define DIRECT_MULTIDIM_ELEM(v, n)
constexpr int FIRST_DEFOCUS_PARAMETER
void log10(Image< double > &op)
double Cs
Spherical aberration (in milimeters). Typical value 5.6.
Definition: ctf.h:246
#define DEBUG_MODEL_TEXTFILE
void generateModelSoFar_fast(MultidimArray< double > &I, bool apply_log)
constexpr int PARAMETRIC_CTF_PARAMETERS
void initZeros()
Definition: matrix1d.h:592
bool show_optimization
Show convergence values.
void FourierTransform(T &v, T1 &V, bool getCopy=true)
Definition: xmipp_fftw.h:166
#define XMIPP_MIN(x, y)
Definition: xmipp_macros.h:181
void forcePhysicalMeaning()
Definition: ctf.cpp:1055
static void defineBasicParams(XmippProgram *program)
Define basic parameters.
void defineParams()
Define Parameters.
double Defocus
Defocus (in Angstroms). Negative values are underfocused.
Definition: ctf.h:244
double steps
#define YY(v)
Definition: matrix1d.h:93
Downsampling performed to estimate the CTF.
void saveIntermediateResults_fast(const FileName &fn_root, bool generate_profiles)
void error(char *s)
Definition: tools.cpp:107
void matlab_filter(Matrix1D< double > &B, Matrix1D< double > &A, const MultidimArray< double > &X, MultidimArray< double > &Y, MultidimArray< double > &Z)
Definition: filters.cpp:4256
#define FOR_ALL_ELEMENTS_IN_ARRAY1D(v)
Matrix1D< double > adjust
Set of parameters for the complete adjustment of the CTF.
void produceSideInfo()
Produce side information.
#define MATRIX1D_ARRAY(v)
Definition: matrix1d.h:58
int modelSimplification
Model simplification.
double VPP_radius
Definition: ctf.h:306
FileName withoutExtension() const
Iceness of the micrograph.
double min_freq
Minimum frequency to adjust.
std::string String
Definition: xmipp_strings.h:34
void assignCTFfromParameters_fast(double *p, CTFDescription1D &ctf1Dmodel, int ia, int l)
String formatString(const char *format,...)
void initZeros()
Definition: matrix2d.h:626
int textToInteger(const char *str)
double y0
In the case of local CTF determination x0,xF,y0,yF determines the region where the CTF is determined...
Definition: ctf.h:267
doublereal * u
void assignParametersFromCTF_fast(const CTFDescription1D &ctfmodel, double *p, int ia, int l)
The CTF is valid within (x0,y0) to (xF,yF) in the micrograph coordinates.
double Q0
Factor for the importance of the Amplitude contrast.
Definition: ctf.h:261
ProgCTFEstimateFromPSDFast * global_prm
double x0
In the case of local CTF determination x0,xF,y0,yF determines the region where the CTF is determined...
Definition: ctf.h:263
constexpr int K
ProgClassifyCL2D * prm
#define ASSIGN_CTF_PARAM(index, paramName)
double kV
Accelerating Voltage (in KiloVolts)
Definition: ctf.h:242
void initZeros(const MultidimArray< T1 > &op)
bool enable_CTFnoise
Enable CTFnoise part.
Definition: ctf.h:273
double xF
In the case of local CTF determination x0,xF,y0,yF determines the region where the CTF is determined...
Definition: ctf.h:265
void initConstant(T val)
Definition: matrix1d.cpp:83
double fmax
double yF
In the case of local CTF determination x0,xF,y0,yF determines the region where the CTF is determined...
Definition: ctf.h:269
int * n
double fitness(double *p)
constexpr int BACKGROUND_CTF_PARAMETERS
T computeMax() const
void digfreq2contfreq(const Matrix1D< double > &digfreq, Matrix1D< double > &contfreq, double pixel_size)
Definition: xmipp_fft.h:125
The CTF is valid within (x0,y0) to (xF,yF) in the micrograph coordinates.
constexpr int SQRT_CTF_PARAMETERS