Xmipp  v3.23.11-Nereus
Public Member Functions | List of all members
ProgFSO Class Reference

#include <resolution_fso.h>

Inheritance diagram for ProgFSO:
Inheritance graph
[legend]
Collaboration diagram for ProgFSO:
Collaboration graph
[legend]

Public Member Functions

void defineParams ()
 
void readParams ()
 
void run ()
 
- Public Member Functions inherited from XmippProgram
const char * getParam (const char *param, int arg=0)
 
const char * getParam (const char *param, const char *subparam, int arg=0)
 
int getIntParam (const char *param, int arg=0)
 
int getIntParam (const char *param, const char *subparam, int arg=0)
 
double getDoubleParam (const char *param, int arg=0)
 
double getDoubleParam (const char *param, const char *subparam, int arg=0)
 
float getFloatParam (const char *param, int arg=0)
 
float getFloatParam (const char *param, const char *subparam, int arg=0)
 
void getListParam (const char *param, StringVector &list)
 
int getCountParam (const char *param)
 
bool checkParam (const char *param)
 
bool existsParam (const char *param)
 
void addParamsLine (const String &line)
 
void addParamsLine (const char *line)
 
ParamDefgetParamDef (const char *param) const
 
virtual void quit (int exit_code=0) const
 
virtual int tryRun ()
 
void initProgress (size_t total, size_t stepBin=60)
 
void setProgress (size_t value=0)
 
void endProgress ()
 
void processDefaultComment (const char *param, const char *left)
 
void setDefaultComment (const char *param, const char *comment)
 
virtual void initComments ()
 
void setProgramName (const char *name)
 
void addUsageLine (const char *line, bool verbatim=false)
 
void clearUsage ()
 
void addExampleLine (const char *example, bool verbatim=true)
 
void addSeeAlsoLine (const char *seeAlso)
 
void addKeywords (const char *keywords)
 
const char * name () const
 
virtual void usage (int verb=0) const
 
virtual void usage (const String &param, int verb=2)
 
int version () const
 
virtual void show () const
 
virtual void read (int argc, const char **argv, bool reportErrors=true)
 
virtual void read (int argc, char **argv, bool reportErrors=true)
 
void read (const String &argumentsLine)
 
 XmippProgram ()
 
 XmippProgram (int argc, const char **argv)
 
virtual ~XmippProgram ()
 

Additional Inherited Members

- Public Attributes inherited from XmippProgram
bool doRun
 
bool runWithoutArgs
 
int verbose
 Verbosity level. More...
 
int debug
 
- Protected Member Functions inherited from XmippProgram
void defineCommons ()
 
- Protected Attributes inherited from XmippProgram
int errorCode
 
ProgramDefprogDef
 Program definition and arguments parser. More...
 
std::map< String, CommentListdefaultComments
 
int argc
 Original command line arguments. More...
 
const char ** argv
 

Detailed Description

Definition at line 38 of file resolution_fso.h.

Member Function Documentation

◆ defineParams()

void ProgFSO::defineParams ( )
virtual

Function in which the param of each Program are defined.

Reimplemented from XmippProgram.

Definition at line 36 of file resolution_fso.cpp.

37 {
38  addUsageLine("Calculate Fourier Shell Occupancy - FSO curve - via directional FSC measurements.");
39  addUsageLine("Following outputs are generated:");
40  addUsageLine(" 1) FSO curve");
41  addUsageLine(" 2) Global resolution from FSO and FSC");
42  addUsageLine(" 3) 3DFSC");
43  addUsageLine(" 4) Anisotropic filter");
44  addUsageLine("Reference: J.L. Vilas, H.D. Tagare, XXXXX (2021)");
45  addUsageLine("+* Fourier Shell Occupancy (FSO)", true);
46  addUsageLine("+ The Fourier Shell Occupancy Curve can be obtained from a set of directional FSC (see below).");
47  addUsageLine("+ To do that, two half maps are used to determine the Global FSC at threshold 0.143. Then, the ratio between the number");
48  addUsageLine("+ of directions with resolution higher (better) than the Global resolution and the total number of measured directions is");
49  addUsageLine("+ calculated at different frequencies (resolutions). Note that this ratio is between 0 (resolution of all directions is worse than the global FSC)");
50  addUsageLine("+ resolution than the global FSC) and 1 (all directions present better resolution than the FSC) at a given resolution.");
51  addUsageLine("+ In the particular case, FSO curve takes the value of 0.5 (FSO=0.5), then half of the directions are better, and.");
52  addUsageLine("+ the other half are worse than the FSC, this situation occurs at the resoltuion of the map. It means the FSO = 0.5 at the ");
53  addUsageLine("+ FSC resolution. A map is isotropic if all directional resolution are similar, and anisotropic is there are significant resolution values along");
54  addUsageLine("+ different directions. Thus, when the FSO presents a sharp cliff, a step-like function, the map will be isotropic.");
55  addUsageLine("+ In contrast, when the OFSC shows a slope the map will be anisotropic. The lesser slope the higher resolution isotropy.");
56  addUsageLine("+ ");
57  addUsageLine("+* Directional Fourier Shell Correlation (dFSC)", true);
58  addUsageLine("+ This program estimates the directional FSC between two half maps along all posible directions on the projection sphere.");
59  addUsageLine("+ The directionality is measured by means of conical-like filters in Fourier Space. To avoid possible Gibbs effects ");
60  addUsageLine("+ the filters are gaussian functions with their respective maxima along the filtering direction. A set of 321 directions ");
61  addUsageLine("+ is used to cover the projection sphere, computing for each direction the directional FSC at 0.143 between the two half maps.");
62  addUsageLine("+ The result is a set of 321 FSC curves (321 is the number of analyzed directions, densely covering the projection sphere).");
63  addUsageLine("+ The 3DFSC is then obtained from all curves by interpolation. Note that as well as it occurs with global FSC, the directional FSC is mask dependent.");
64  addUsageLine(" ");
65  addUsageLine("+* Resolution Distribution and 3DFSC", true);
66  addUsageLine("+ The directional-FSC, dFSC is estimated along 321 directions on the projection sphere. For each direction the corresponding");
67  addUsageLine("+ resolution is determined. Thus, it is possible to determine the resolution distribution on the projection sphere.");
68  addUsageLine("+ This distribution is saved in the output metadata named resolutionDistribution.xmd. Also by means of all dFSC, the 3DFSC");
69  addUsageLine("+ is calculated and saved as 3dFSC.mrc, which gives an idea about the information distributionin Fourier Space.");
70  addUsageLine(" ");
71  addUsageLine(" ");
72  addSeeAlsoLine("resolution_fsc");
73 
74  addParamsLine(" --half1 <input_file> : Input Half map 1");
75  addParamsLine(" --half2 <input_file> : Input Half map 2");
76 
77  addParamsLine(" [-o <output_folder=\"\">] : Folder where the results will be stored.");
78 
79  addParamsLine(" [--sampling <Ts=1>] : (Optical) Pixel size (Angstrom). If it is not provided by default will be 1 A/px.");
80  addParamsLine(" [--mask <input_file=\"\">] : (Optional) Smooth mask to remove noise. If it is not provided, the computation will be carried out without mask.");
81 
82  addParamsLine(" [--anglecone <ang_con=17>] : (Optional) Angle Cone (angle between the axis and the generatrix) for estimating the directional FSC");
83  addParamsLine(" [--threshold <thrs=0.143>] : (Optional) Threshold for the FSC/directionalFSC estimation ");
84 
85  addParamsLine(" [--threedfsc_filter] : (Optional) Put this flag to estimate the 3DFSC, and apply it as low pass filter to obtain a directionally filtered map. It mean to apply an anisotropic filter.");
86 
87  addParamsLine(" [--threads <Nthreads=1>] : (Optional) Number of threads to be used");
88 
89  addExampleLine("Resolution of two half maps half1.mrc and half2.mrc with a sampling rate of 2 A/px", false);
90  addExampleLine("xmipp_resolution_fso --half1 half1.mrc --half2 half2.mrc --sampling_rate 2 ");
91  addExampleLine("Resolution of two half maps half1.mrc and half2.mrc with a sampling rate of 2 A/px and a mask mask.mrc", false);
92  addExampleLine("xmipp_resolution_fso --half1 half1.mrc --half2 half2.mrc --mask mask.mrc --sampling_rate 2 ");
93 }
void addSeeAlsoLine(const char *seeAlso)
void addExampleLine(const char *example, bool verbatim=true)
void addUsageLine(const char *line, bool verbatim=false)
void addParamsLine(const String &line)

◆ readParams()

void ProgFSO::readParams ( )
virtual

Function in which each program will read parameters that it need. If some error occurs the usage will be printed out.

Reimplemented from XmippProgram.

Definition at line 95 of file resolution_fso.cpp.

96 {
97  fnhalf1 = getParam("--half1");
98  fnhalf2 = getParam("--half2");
99  fnOut = getParam("-o");
100 
101  sampling = getDoubleParam("--sampling");
102  fnmask = getParam("--mask");
103  ang_con = getDoubleParam("--anglecone");
104  thrs = getDoubleParam("--threshold");
105  do_3dfsc_filter = checkParam("--threedfsc_filter");
106 
107  Nthreads = getIntParam("--threads");
108 }
double getDoubleParam(const char *param, int arg=0)
const char * getParam(const char *param, int arg=0)
FileName fnOut
#define sampling
bool checkParam(const char *param)
int getIntParam(const char *param, int arg=0)

◆ run()

void ProgFSO::run ( )
virtual

This function will be start running the program. it also should be implemented by derived classes.

Reimplemented from XmippProgram.

Definition at line 1309 of file resolution_fso.cpp.

1310  {
1311  std::cout << "Starting ... " << std::endl << std::endl;
1312 
1313  MultidimArray<double> half1, half2;
1314  MultidimArray<double> &phalf1 = half1, &phalf2 = half2;
1315 
1316  //This read the data and applies a fftshift to in the next step compute the fft
1317  prepareData(half1, half2);
1318 
1319  //Computing the FFT
1320  FourierTransformer transformer2(FFTW_BACKWARD), transformer1(FFTW_BACKWARD);
1321  transformer1.setThreadsNumber(Nthreads);
1322  transformer2.setThreadsNumber(Nthreads);
1323 
1324  transformer1.FourierTransform(half1, FT1, false);
1325  transformer2.FourierTransform(half2, FT2, false);
1326 
1327  // Defining frequencies freq_fourier_x,y,z and freqMap
1328  // The number of frequencies in each shell freqElem is determined
1329  defineFrequencies(FT1, phalf1);
1330 
1331  half1.clear();
1332  half2.clear();
1333 
1334  // Storing the shell of both maps as vectors global
1335  // The global FSC is also computed
1336  MultidimArray<double> freq;
1337  arrangeFSC_and_fscGlobal(sampling, thrs, freq);
1338 
1339  FT2.clear();
1340 
1341  // Generating the set of directions to be analyzed
1342  // And converting the cone angle to radians
1343  generateDirections(angles, true);
1344  ang_con = ang_con*PI/180.0;
1345 
1346  // Preparing the metadata for storing the FSO
1347  MultidimArray<double> resDirFSC(angles.mdimx);//, aniParam;
1348  //aniParam.initZeros(xvoldim/2+1);
1349 
1350  // Computing directional FSC and 3DFSC
1351  // Create one copy for each thread
1352  std::vector<MultidimArray<float>> threeD_FSCs(Nthreads);
1353  std::vector<MultidimArray<float>> normalizationMaps(Nthreads);
1354  std::vector<MultidimArray<float>> aniParams(Nthreads);
1355  for (auto & ma : threeD_FSCs) {
1356  ma.initZeros(real_z1z2);
1357  }
1358  for (auto & ma : normalizationMaps) {
1359  ma.initZeros(real_z1z2);
1360  }
1361  for (auto & ma : aniParams) {
1362  ma.initZeros(xvoldim/2+1);
1363  }
1364 
1365  // Binham Test
1366  // We will have as many vectors as threads
1367  // Each thread considers a vector with the matrices of the Bingham test
1368  // instantiate vector object of type vector<Matrix2D<float>>
1369  std::vector<std::vector<Matrix2D<double>>> isotropyMatrices;
1370 
1371  // resize the vector to `freq.nzyxdim` elements of type vector<float>, each having size `C`
1372  isotropyMatrices.resize(Nthreads, std::vector<Matrix2D<double>>(freq.nzyxdim));
1373 
1374  // Each component of the vector is a 0-matrix (null matrix)
1375  for (auto & im : isotropyMatrices)
1376  {
1377  for (auto & m : im)
1378  m.initZeros(3,3);
1379  }
1380 
1381  ctpl::thread_pool threadPool;
1382  threadPool.resize(Nthreads);
1383  auto futures = std::vector<std::future<void>>();
1384  futures.reserve(angles.mdimx);
1385 
1386  for (size_t k = 0; k<angles.mdimx; k++)
1387  {
1388  futures.emplace_back(threadPool.push(
1389  [k, this, &resDirFSC, &threeD_FSCs, &normalizationMaps, &aniParams, &isotropyMatrices](int thrId){
1390  float rot = MAT_ELEM(angles, 0, k);
1391  float tilt = MAT_ELEM(angles, 1, k);
1392 
1393  double resInterp = -1;
1394  MultidimArray<float> fsc;
1395 
1396  auto &threeD_FSC = threeD_FSCs.at(thrId);
1397  auto &normalizationMap = normalizationMaps.at(thrId);
1398  auto &freqMat = isotropyMatrices.at(thrId);
1399  // Estimating the direction FSC along the direction given by rot and tilt
1400  fscDir_fast(fsc, rot, tilt, threeD_FSC, normalizationMap, thrs, resInterp, freqMat, k);
1401 
1402  printf ("Direction %zu/%zu -> %.2f A \n", k, angles.mdimx, resInterp);
1403 
1404  dAi(resDirFSC, k) = resInterp;
1405 
1406  // Updating the FSO curve
1407  anistropyParameter(fsc, aniParams.at(thrId), thrs);
1408  }));
1409  }
1410 
1411  // wait till done
1412  for (auto &f : futures) {
1413  f.get();
1414  }
1415 
1416  std::cout << "----- Directional resolution estimated -----" << std::endl << std::endl;
1417  std::cout << "Preparing results ..." << std::endl;
1418 
1419  // merge results from multiple threads
1420  for (size_t i = 1; i < aniParams.size(); ++i) {
1421  aniParams.at(0) += aniParams.at(i);
1422  }
1423 
1424  // For the Bingham Test
1425  // merge results from multiple threads
1426  for (size_t i = 0; i < freq.nzyxdim; ++i)
1427  {
1428  for (size_t j = 1; j<Nthreads; ++j)
1429  {
1430  isotropyMatrices.at(0)[i] += isotropyMatrices.at(j)[i];
1431  }
1432  isotropyMatrices.at(0)[i] /= aniParams.at(0)[i];
1433  }
1434 
1435  //auto &freqMat = isotropyMatrices.at(0);
1436  auto &aniParam = aniParams.at(0);
1437  MultidimArray<double> isotropyMatrix;
1438  isotropyMatrix.initZeros(freq.nzyxdim);
1439 
1440  for (size_t i = 0; i< freq.nzyxdim; ++i)
1441  {
1442  double trT2 = 0;
1443  if (aniParams.at(0)[i] >0)
1444  {
1445  // Let us define T = 1/n*Sum(wi*xi*xi) => Tr(T^2) = x*x + y*y + z*z;
1446  //This is the Bingham Test (1/2)(p-1)*(p-2)*n*Sum(Tr(T^2) - 1/p)
1447  //std::cout << isotropyMatrices.at(0)[i] << aniParams.at(0)[i] << std::endl;
1448  Matrix2D<double> T2;
1449  Matrix2D<double> T;
1450  T = isotropyMatrices.at(0)[i];//freqMat[i]/DIRECT_MULTIDIM_ELEM(aniParam, i);
1451  T2 = T*T;
1452  trT2 = T2.trace();
1453  double pdim = 3;
1454  dAi(isotropyMatrix, i) = 0.5*pdim*(pdim+2)*(2*aniParams.at(0)[i])*(trT2 - 1./pdim);
1455  // The factor 2 is because we need to compute the point in the whole sphere, but currently
1456  // we are measuing half of the sphere due to the symmetry of the problem
1457  // S = 0.5 * p * (p+2) * n * (trace(T2) - 1/p); Where p is the
1458  // dimension of the sphere (p=3) and n the number of points to
1459  // determine if they are uniformly or not. T = x*x';
1460 
1461  // The hypohtesis test considers p = 0.05.
1462  // p=0.05; nu = 5; x = chi2inv(p,nu);
1463  }
1464  }
1465 
1466 
1467  // ANISOTROPY CURVE
1468  aniParams.at(0) /= (double) angles.mdimx;
1469  for (size_t k = 0; k<5; k++)
1470  DIRECT_MULTIDIM_ELEM(aniParams.at(0), k) = 1.0;
1471  MetaDataVec mdani;
1472  saveAnisotropyToMetadata(mdani, freq, aniParams.at(0), isotropyMatrix);
1473 
1474 
1475  // DIRECTIONAL RESOLUTION DISTRIBUTION ON THE PROJECTION SPHERE
1476  FileName fn;
1477  fn = fnOut+"/Resolution_Distribution.xmd";
1478 
1479  resolutionDistribution(resDirFSC, fn);
1480 
1481 
1482  // 3DFSC and ANISOTROPIC FILTER
1483  if (do_3dfsc_filter)
1484  {
1485  // HALF 3DFSC MAP
1486  MultidimArray<double> d3_FSCMap;
1487  MultidimArray<double> d3_aniFilter;
1488  d3_FSCMap.resizeNoCopy(FT1);
1489  d3_FSCMap.initConstant(0);
1490  d3_aniFilter.resizeNoCopy(FT1);
1491  d3_aniFilter.initConstant(0);
1492 
1493  // merge results from multiple threads
1494  for (size_t i = 1; i < Nthreads; ++i) {
1495  threeD_FSCs.at(0) += threeD_FSCs.at(i);
1496  normalizationMaps.at(0) += normalizationMaps.at(i);
1497  }
1498  auto &threeD_FSC = threeD_FSCs.at(0);
1499  auto &normalizationMap = normalizationMaps.at(0);
1500 
1502  {
1503  double value = DIRECT_MULTIDIM_ELEM(threeD_FSC, n) /= DIRECT_MULTIDIM_ELEM(normalizationMap, n);
1504  if (std::isnan(value))
1505  value = 1.0;
1506 
1507  size_t idx = DIRECT_MULTIDIM_ELEM(arr2indx, n);
1508  DIRECT_MULTIDIM_ELEM(d3_FSCMap, idx) = value;
1509 
1510  if (DIRECT_MULTIDIM_ELEM(threeD_FSC, n)> thrs)//&& (DIRECT_MULTIDIM_ELEM(aniFilter, n) <1))
1511  {
1512  DIRECT_MULTIDIM_ELEM(d3_aniFilter, idx) = 1; //;DIRECT_MULTIDIM_ELEM(aniFilter, n) = 1;
1513  }
1514  else
1515  {
1516  DIRECT_MULTIDIM_ELEM(d3_aniFilter, idx) = value;//DIRECT_MULTIDIM_ELEM(aniFilter, n);
1517  }
1518 
1519  }
1520 
1521  // This code fix the empty line line in Fourier space
1522  size_t auxVal;
1523  auxVal = YSIZE(d3_FSCMap)/2;
1524 
1525  size_t j = 0;
1526  for(size_t i=(auxVal+1); i<YSIZE(d3_FSCMap); ++i)
1527  {
1528  for(size_t k=0; k<ZSIZE(d3_FSCMap); ++k)
1529  {
1530  DIRECT_A3D_ELEM(d3_FSCMap,k,i,0) = DIRECT_A3D_ELEM(d3_FSCMap,k,i,1);
1531  DIRECT_A3D_ELEM(d3_aniFilter,k,i,0) = DIRECT_A3D_ELEM(d3_aniFilter,k,i,1);
1532  }
1533  }
1534  size_t i=0;
1535  for(size_t k=0; k<ZSIZE(d3_FSCMap); ++k)
1536  {
1537  DIRECT_A3D_ELEM(d3_FSCMap,k,0,0) = DIRECT_A3D_ELEM(d3_FSCMap,k,0, 1);
1538  DIRECT_A3D_ELEM(d3_aniFilter,k,0,0) = DIRECT_A3D_ELEM(d3_aniFilter,k,0,1);
1539  }
1540 
1541 
1542  Image<double> img;
1543  img() = d3_FSCMap;
1544  img.write("threeD_FSC.mrc");
1545 
1546  double sigma = 3;
1547 
1548  realGaussianFilter(d3_aniFilter, sigma);
1549 
1550  // DIRECTIONAL FILTERED MAP
1551  MultidimArray<double> filteredMap;
1552  //directionalFilter(FT1, d3_aniFilter, filteredMap, xvoldim, yvoldim, zvoldim);
1553  directionalFilterHalves(FT1, d3_aniFilter);
1554 
1555  //FULL 3DFSC MAP
1556  fn = fnOut+"/3dFSC.mrc";
1557  createFullFourier(d3_FSCMap, fn, xvoldim, yvoldim, zvoldim);
1558  }
1559 
1560 
1561 
1562  std::cout << "-------------Finished-------------" << std::endl;
1563 }
#define dAi(v, i)
#define YSIZE(v)
void resizeNoCopy(const MultidimArray< T1 > &v)
auto push(F &&f, Rest &&... rest) -> std::future< decltype(f(0, rest...))>
Definition: ctpl.h:152
T trace() const
Definition: matrix2d.cpp:1304
void write(const FileName &name="", size_t select_img=ALL_IMAGES, bool isStack=false, int mode=WRITE_OVERWRITE, CastWriteMode castMode=CW_CAST, int _swapWrite=0)
void initConstant(T val)
void resize(int nThreads)
Definition: ctpl.h:70
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
double * f
FileName fnOut
#define sampling
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define ZSIZE(v)
#define DIRECT_MULTIDIM_ELEM(v, n)
for(j=1;j<=i__1;++j)
#define DIRECT_A3D_ELEM(v, k, i, j)
#define j
int m
void realGaussianFilter(MultidimArray< double > &img, double sigma)
size_t mdimx
Definition: matrix2d.h:410
void initZeros(const MultidimArray< T1 > &op)
#define PI
Definition: tools.h:43
int * n

The documentation for this class was generated from the following files: