Xmipp  v3.23.11-Nereus
Classes | Functions
adjust_ctf (Adjust CTF parameters to PSD)
Collaboration diagram for adjust_ctf (Adjust CTF parameters to PSD):

Classes

class  ProgCTFEstimateFromPSDFast
 

Functions

double ROUT_Adjust_CTFFast (ProgCTFEstimateFromPSDFast &prm, CTFDescription1D &output_ctfmodel, bool standalone=true)
 

Detailed Description

Function Documentation

◆ ROUT_Adjust_CTFFast()

double ROUT_Adjust_CTFFast ( ProgCTFEstimateFromPSDFast prm,
CTFDescription1D output_ctfmodel,
bool  standalone = true 
)

Core of the Adjust CTF routine. This is the routine which does everything. It returns the fitting error committed in the best fit.

Definition at line 1417 of file ctf_estimate_from_psd_fast.cpp.

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 }
#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)
MultidimArray< double > * f
Image< double > ctftomodel
CTF amplitude to model.
FileName removeLastExtension() const
void read(const FileName &inFile, const std::vector< MDLabel > *desiredLabels=nullptr, bool decomposeStack=true) override
constexpr int FIRST_SQRT_PARAMETER
Matrix1D< double > * adjust_params
double DeltafV
Defocus in V (in Angstroms). Negative values are underfocused.
Definition: ctf.h:830
double Tm
Sampling rate.
double espr
Definition: ctf.h:251
void show()
Show parameters.
double evaluateIceness(const MultidimArray< double > &enhanced_ctftomodel, double Tm)
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
FileName fn_psd
CTF filename.
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
double azimuthal_angle
Azimuthal angle (between X and U) in degrees.
Definition: ctf.h:832
Score of the fitting.
void produceSideInfo()
Produce side information.
#define XX(v)
Definition: matrix1d.h:85
double CTF_fitness_fast(double *, void *)
bool setValue(const MDObject &mdValueIn, size_t id)
size_t firstRowId() const override
bool noDefocusEstimate
No defocus estimate.
void resize(size_t Xdim, bool copy=true)
Definition: matrix1d.h:410
constexpr int ALL_CTF_PARAMETERS
double CTF_fitness(double *p, void *vprm)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
bool refineAmplitudeContrast
Refine amplitude contrast.
#define DIRECT_MULTIDIM_ELEM(v, n)
double Cs
Spherical aberration (in milimeters). Typical value 5.6.
Definition: ctf.h:246
#define DEBUG_MODEL_TEXTFILE
void initZeros()
Definition: matrix1d.h:592
bool show_optimization
Show convergence values.
void forcePhysicalMeaning()
Definition: ctf.cpp:1055
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)
Matrix1D< double > adjust
Set of parameters for the complete adjustment of the CTF.
#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
String formatString(const char *format,...)
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
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
ProgClassifyCL2D * prm
double kV
Accelerating Voltage (in KiloVolts)
Definition: ctf.h:242
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 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
The CTF is valid within (x0,y0) to (xF,yF) in the micrograph coordinates.