Xmipp  v3.23.11-Nereus
angular_assignment_mag.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Jeison Méndez García (jmendez@utp.edu.co)
4  *
5  * Instituto de Investigaciones en Matemáticas Aplicadas y en Sistemas -- IIMAS
6  * Universidad Nacional Autónoma de México -UNAM
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 "angular_assignment_mag.h"
30 #include "data/projection.h"
33 #include <mutex>
34 
35 #include <fstream>
36 #include <ctime>
37 #include <unistd.h>
38 
40  produces_a_metadata = true;
42  rank=0;
43  Nprocessors=1;
44 }
45 
47 
50  //usage
51  addUsageLine( "Generates a list of candidates for angular assignment for each experimental image");
52  addParamsLine(" -ref <md_file> : Metadata file with input reference projections");
53  addParamsLine(" [-odir <outputDir=\".\">] : Output directory");
54  addParamsLine(" [--sym <symfile=c1>] : Enforce symmetry in projections");
55  addParamsLine(" [-sampling <sampling=1.>] : sampling");
56  addParamsLine(" [-angleStep <angStep=3.>] : angStep");
57  addParamsLine(" [--maxShift <maxShift=-1.>] : Maximum shift allowed (+-this amount)");
58  addParamsLine(" [--Nsimultaneous <Nprocessors=1>] : Nsimultaneous");
59  addParamsLine(" [--refVol <refVolFile=NULL>] : reference volume to be reprojected when comparing with previous alignment");
60  addParamsLine(" [--useForValidation] : Use the program for validation");
61  addParamsLine(" [--thr <threads=4>] : How many threads to use");
62 }
63 
64 // Read arguments ==========================================================
67  fnRef = getParam("-ref");
68  fnDir = getParam("-odir");
69  sampling = getDoubleParam("-sampling");
70  angStep= getDoubleParam("-angleStep");
72  fnSym = getParam("--sym");
73  maxShift = getDoubleParam("--maxShift");
74  inputReference_volume = getParam("--refVol");
75  useForValidation=checkParam("--useForValidation");
76  threads = getIntParam("--thr");
77  threadPool.resize(threads);
78  transformersForImages.resize(threads);
79  ccMatrixBestCandidTransformers.resize(threads);
80  ccMatrixShifts.resize(threads);
81 }
82 
83 // Show ====================================================================
85  if (verbose > 0) {
86  printf("%d reference images of %d x %d\n",int(sizeMdRef),int(Xdim),int(Ydim));
87  printf("%d exp images of %d x %d in this group\n", int(sizeMdIn),int(Xdim), int(Ydim));
88  std::cout << "Sampling: " << sampling << std::endl;
89  std::cout << "Angular step: " << angStep << std::endl;
90  std::cout << "Maximum shift: " << maxShift << std::endl;
91  std::cout << "threads: " << threads << std::endl;
92  if(useForValidation){
93  std::cout << "ref vol size: " << refXdim <<" x "<< refYdim <<" x "<< refZdim << std::endl;
94  std::cout << "useForValidation : " << useForValidation << std::endl;
95  }
97  std::cout << "Input references: " << fnRef << std::endl;
98  }
99 }
100 
101 /*
102  * In this method, for each direction, I look for neighbors within some distance
103  * */
104 void ProgAngularAssignmentMag::computingNeighborGraph() {
105  std::vector< std::vector<int> > allNeighborsjp;
106  std::vector< std::vector<double> > allWeightsjp;
107  Matrix1D<double> distanceToj;
108  Matrix1D<double> dirj;
109  Matrix1D<double> dirjp;
110  double maxSphericalDistance = angStep*2.;
111  std::cout<< "processing neighbors graph..."<<std::endl;
112 
113  for (auto &rowj : mdRef){
114  double rotj;
115  double tiltj;
116  double psij;
117  rowj.getValue(MDL_ANGLE_ROT, rotj);
118  rowj.getValue(MDL_ANGLE_TILT, tiltj);
119  rowj.getValue(MDL_ANGLE_PSI, psij);
120  distanceToj.initZeros(sizeMdRef);
121  Euler_direction(rotj, tiltj, psij, dirj);
122  std::vector<int> neighborsjp;
123  std::vector<double> weightsjp;
124  double thisSphericalDistance = 0.;
125  int jp = 0;
126  for (auto &rowjp : mdRef){
127  double rotjp;
128  double tiltjp;
129  double psijp;
130  rowjp.getValue(MDL_ANGLE_ROT, rotjp);
131  rowjp.getValue(MDL_ANGLE_TILT, tiltjp);
132  rowjp.getValue(MDL_ANGLE_PSI, psijp);
133  Euler_direction(rotjp, tiltjp, psijp, dirjp);
134  thisSphericalDistance = RAD2DEG(spherical_distance(dirj, dirjp));
135 
136  if (thisSphericalDistance < maxSphericalDistance) {
137  neighborsjp.emplace_back(jp);
138  double val = exp(-thisSphericalDistance / maxSphericalDistance);
139  weightsjp.emplace_back(val);
140  }
141  jp++;
142  }
143  allNeighborsjp.emplace_back(neighborsjp);
144  allWeightsjp.emplace_back(weightsjp);
145  }// END FOR_ALL_OBJECTS_IN_METADATA(mdRef)
146 
147  // compute Laplacian Matrix
148  DMatrix L_mat;
149  computeLaplacianMatrix(L_mat, allNeighborsjp, allWeightsjp);
150 
151  // from diagSymMatrix3x3 method in resolution_directional.cpp
153  B.resizeNoCopy(L_mat);
154  B.initIdentity();
155  generalizedEigs(L_mat, B, eigenvalues, eigenvectors);
156 
157  // save eigenvalues y eigenvectors files
158  String fnEigenVal = formatString("%s/outEigenVal.txt", fnDir.c_str());
159  eigenvalues.write(fnEigenVal);
160  String fnEigenVect = formatString("%s/outEigenVect.txt", fnDir.c_str());
161  eigenvectors.write(fnEigenVect);
162 }
163 
164 /* Laplacian Matrix is basic for signal graph processing stage
165  * is computed only once within preProcess() method */
166 void ProgAngularAssignmentMag::computeLaplacianMatrix (Matrix2D<double> &matL,
167  const std::vector< std::vector<int> > &allNeighborsjp,
168  const std::vector< std::vector<double> > &allWeightsjp) const {
169 
170  matL.initZeros(sizeMdRef,sizeMdRef);
171 
172  for(int i=0; i<sizeMdRef; ++i){
173  std::vector<int> neighborsjp = allNeighborsjp[i];
174  std::vector<double> weightsjp = allWeightsjp[i];
175  double sumWeight = 0.;
176  int indx = 0;
177  int j = -1;
178  for(auto it=neighborsjp.begin(); it!=neighborsjp.end(); ++it){
179  j += 1;
180  indx = (*it);
181  MAT_ELEM(matL,i,indx) = -weightsjp[j];
182  sumWeight += weightsjp[j];
183  }
184  MAT_ELEM(matL,i,i) = sumWeight - 1.; // -1 because is necessary to remove the "central" weight
185  }
186 }
187 
188 unsigned long long getTotalSystemMemory()
189 {
190  long pages = sysconf(_SC_PHYS_PAGES);
191  long page_size = sysconf(_SC_PAGE_SIZE);
192  return pages * page_size;
193 }
194 
195 void ProgAngularAssignmentMag::checkStorageSpace() {
196  // for storage of rot and tilt of reference images
197  referenceRot.resize(sizeMdRef);
198  referenceTilt.resize(sizeMdRef);
199  if (rank == 0) {
200  std::cout << "processing reference library..." << std::endl;
201  // memory check
202  size_t dataSize = Xdim * Ydim * sizeMdRef * sizeof(double);
203  size_t matrixSize = sizeMdRef * sizeMdRef * sizeof(double);
204  size_t polarFourierSize = n_bands * n_ang2 * sizeMdRef
205  * sizeof(std::complex<double>);
206 
207  size_t totMemory = dataSize + matrixSize + polarFourierSize;
208  totMemory = memoryUtils::MB(totMemory) * Nprocessors;
209  std::cout << "approx. memory to allocate: " << totMemory << " MB"
210  << std::endl;
211  std::cout << "simultaneous MPI processes: " << Nprocessors << std::endl;
212 
213  size_t available = getTotalSystemMemory();
214  available = memoryUtils::MB(available);
215  std::cout << "total available system memory: " << available << " MB"
216  << std::endl;
217  available -= 1500;
218 
219  if (available < totMemory) {
221  "You don't have enough memory. Try to use less MPI processes.");
222  }
223  }
224 }
225 
226 void ProgAngularAssignmentMag::processGallery(FileName &fnImgRef) {
227  // reference image related
228  Image<double> ImgRef;
229  MultidimArray<double> MDaRef((int) Ydim, (int) Xdim);
232  MultidimArray<double> MDaRefFM;
233  MultidimArray<double> MDaRefFMs;
234  MultidimArray<double> MDaRefFMs_polarPart((int) n_bands, (int) n_ang2);
235  MultidimArray<std::complex<double> > MDaRefFMs_polarF;
236 
237  MultidimArray<double> refPolar((int) n_rad, (int) n_ang2);
239  int j = 0;
240  for (auto &rowj : mdRef) {
241  // reading image
242  rowj.getValue(MDL_IMAGE, fnImgRef);
243  ImgRef.read(fnImgRef);
244  MDaRef = ImgRef();
245  MDaRef.setXmippOrigin();
246  // store to call in processImage method
247  double rot;
248  double tilt;
249  double psi;
250  rowj.getValue(MDL_ANGLE_ROT, rot);
251  rowj.getValue(MDL_ANGLE_TILT, tilt);
252  rowj.getValue(MDL_ANGLE_PSI, psi);
253  referenceRot.at(j) = rot;
254  referenceTilt.at(j) = tilt;
255  // processing reference image
256  vecMDaRef.push_back(MDaRef);
257  transformerImage.FourierTransform(MDaRef, MDaRefF, true);
258  // Fourier of polar magnitude spectra
259  transformerImage.getCompleteFourier(MDaRefF2);
260  FFT_magnitude(MDaRefF2, MDaRefFM);
261  completeFourierShift(MDaRefFM, MDaRefFMs);
262  MDaRefFMs_polarPart = imToPolar(MDaRefFMs, startBand, finalBand);
263  transformerPolarImage.FourierTransform(MDaRefFMs_polarPart, MDaRefFMs_polarF, true);
264  vecMDaRefFMs_polarF.push_back(MDaRefFMs_polarF);
265  j++;
266  }
267 }
268 
269 void ProgAngularAssignmentMag::computeEigenvectors() {
270  // check if eigenvectors file already created
271  String fnEigenVect = formatString("%s/outEigenVect.txt", fnDir.c_str());
272  std::ifstream in;
273  in.open(fnEigenVect.c_str());
274  if (!in) {
275  in.close();
276  // Define the neighborhood graph, Laplacian Matrix and eigendecomposition
277  if (rank == 0)
278  computingNeighborGraph();
279  }
280 
281  // synch with other processors
282  synchronize();
283 
284  // prepare and read from file
285  eigenvectors.clear();
286  eigenvectors.resizeNoCopy(sizeMdRef, sizeMdRef);
287  eigenvectors.read(fnEigenVect);
288 }
289 
291 
293  mdRef.read(fnRef);
294 
295  // size of images
296  size_t Zdim;
297  size_t Ndim;
298  getImageSize(mdIn, Xdim, Ydim, Zdim, Ndim);
299 
300  // some constants
301  n_rad = size_t((double)Xdim / 2.);
302  startBand = size_t((sampling * (double) Xdim) / 80.);
303  finalBand = size_t((sampling * (double) Xdim) / (sampling * 3));
304  n_bands = finalBand - startBand;
305  n_ang = size_t(180);
306  n_ang2 = 2 * n_ang;
307  if (maxShift==-1.){
308  maxShift = .10 * (double)Xdim;
309  }
310 
311  // read reference images
312  FileName fnImgRef;
313  sizeMdRef = (int)mdRef.size();
314 
315  // how many input images
316  sizeMdIn = (int)mdIn.size();
317 
318  computeCircular(); //pre-compute circular mask
319 
320  checkStorageSpace();
321 
322  processGallery(fnImgRef); // process reference gallery
323 
324  computeEigenvectors(); // eigenvectors for graph-signal-processing
325 
326  // Symmetry List
327  if (fnSym != "") {
328  SL.readSymmetryFile(fnSym);
329  for (int sym = 0; sym < SL.symsNo(); sym++) {
330  Matrix2D<double> auxL, auxR;
331  SL.getMatrices(sym, auxL, auxR);
332  auxL.resize(3, 3);
333  auxR.resize(3, 3);
334  L.push_back(auxL);
335  R.push_back(auxR);
336  }
337  } // */
338 
339  if(useForValidation){
340  // read reference volume to be re-projected when comparing previous assignment
341  // If there is no reference available, exit
342  refVol.read(inputReference_volume);
343 
344  refVol().setXmippOrigin();
345  refXdim = (int)XSIZE(refVol());
346  refYdim = (int)YSIZE(refVol());
347  refZdim = (int)ZSIZE(refVol());
348  }
349 }
350 
351 /* Apply graph signal processing to cc-vector using the Laplacian eigen-decomposition
352  * */
353 void ProgAngularAssignmentMag::graphFourierFilter(const Matrix1D<double> &ccVecIn, Matrix1D<double> &ccVecOut ) const {
354  // graph signal processing filtered iGFT
355  Matrix1D<double> ccGFT;
356  ccGFT.initZeros(sizeMdRef);
357  std::vector<double> filt_iGFT_cc(sizeMdRef, 0);
358 
359  Matrix2D<double> eigenvectorTrans = eigenvectors.transpose();
360  ccGFT = eigenvectorTrans*ccVecIn;
361 
362  // define filtering base
363  int cutEig = (sizeMdRef>1000) ? int(.05 * sizeMdRef + 1) : int(.50 * sizeMdRef + 1);
364  for(int k = cutEig; k < sizeMdRef; ++k){
365  VEC_ELEM(ccGFT,k) = 0.;
366  }
367  // apply filter to ccvec
368  ccVecOut = eigenvectors*ccGFT;
369 }
370 
371 void ProgAngularAssignmentMag::processImage(const FileName &fnImg,const FileName &fnImgOut,
372  const MDRow &rowIn, MDRow &rowOut) {
373 
374  // experimental image related
375  Image<double> ImgIn;
376  MultidimArray<double> MDaIn((int)Ydim, (int)Xdim);
379  MultidimArray<double> MDaInFM;
380  MultidimArray<double> MDaInFMs;
381  MultidimArray<double> MDaInFMs_polarPart((int)n_bands, (int)n_ang2);
382  MultidimArray<std::complex<double> > MDaInFMs_polarF;
383 
384  // processing experimental input image
385  ImgIn.read(fnImg);
386  MDaIn = ImgIn();
387  MDaIn.setXmippOrigin();
388  transformerImage.FourierTransform(MDaIn, MDaInF, true);
389  transformerImage.getCompleteFourier(MDaInF2);
390  FFT_magnitude(MDaInF2, MDaInFM);
391  completeFourierShift(MDaInFM, MDaInFMs);
392  MDaInFMs_polarPart = imToPolar(MDaInFMs, startBand, finalBand);
393  transformerPolarImage.FourierTransform(MDaInFMs_polarPart, MDaInFMs_polarF, true);
394 
395  // variables for an initial screening of possible "good" references
396  double psi;
397  double cc_coeff;
398  double Tx;
399  double Ty;
400  int maxAccepted = 8;
401 
402  std::vector<unsigned int> Idx(sizeMdRef, 0);
403 
404  Matrix1D<double> ccvec;
405  ccvec.initZeros(sizeMdRef);
406 
407  std::vector<double> bestTx(sizeMdRef, 0);
408  std::vector<double> bestTy(sizeMdRef, 0);
409  std::vector<double> bestPsi(sizeMdRef, 0);
410 
411  MultidimArray<double> ccMatrixRot;
412  MultidimArray<double> ccVectorRot;
413 
414  // loop over all reference images. Screening of possible "good" references
415  for (int k = 0; k < sizeMdRef; ++k) {
416  // computing relative rotation and shift
417  ccMatrix(MDaInFMs_polarF, vecMDaRefFMs_polarF[k], ccMatrixRot, ccMatrixProcessImageTransformer);
418  maxByColumn(ccMatrixRot, ccVectorRot);
419  peaksFound = 0;
420  std::vector<double> cand(maxAccepted, 0.);
421  psiCandidates(ccVectorRot, cand, XSIZE(ccMatrixRot));
422  bestCand(MDaIn, MDaInF, vecMDaRef[k], cand, psi, Tx, Ty, cc_coeff);
423  // all results are storage for posterior partial_sort
424  Idx[k] = k; // for sorting
425  VEC_ELEM(ccvec,k) = cc_coeff;
426  bestTx[k] = Tx;
427  bestTy[k] = Ty;
428  bestPsi[k] = psi;
429  }
430 
431  // variables for second loop. Selection of "best" reference image
432  std::vector<double> bestTx2(sizeMdRef, 0.);
433  std::vector<double> bestTy2(sizeMdRef, 0.);
434  std::vector<double> bestPsi2(sizeMdRef, 0.);
435 
436  MultidimArray<double> &MDaInAux = ImgIn();
437  MDaInAux.setXmippOrigin();
438  MultidimArray<double> mCurrentImageAligned;
439  double corr, scale;
440  bool flip;
441 
442  double minval, maxval;
443  ccvec.computeMinMax(minval, maxval);
444  double thres = 0.;
445  if (SL.symsNo()<=4)
446  thres = maxval - (maxval - minval) / 3.;
447  else
448  thres = maxval - (maxval - minval) / 2.;
449 
450  // loop over "good" reference images
451  for(int k = 0; k < sizeMdRef; ++k) {
452  if(VEC_ELEM(ccvec,k)>thres){
453  // find rotation and shift using alignImages
455  mCurrentImageAligned = MDaInAux;
456  mCurrentImageAligned.setXmippOrigin();
457  corr = alignImages(vecMDaRef[k], mCurrentImageAligned, M, xmipp_transformation::DONT_WRAP);
458  M = M.inv();
459  transformationMatrix2Parameters2D(M, flip, scale, Tx, Ty, psi);
460 
461  if (maxShift>0 && (fabs(Tx)>maxShift || fabs(Ty)>maxShift))
462  corr /= 3;
463 
464  VEC_ELEM(ccvec, k) = corr;
465  bestTx2[k] = Tx;
466  bestTy2[k] = Ty;
467  bestPsi2[k] = psi;
468 
469  }
470  else{
471  bestTx2[k] = bestTx[k];
472  bestTy2[k] = bestTy[k];
473  bestPsi2[k] = bestPsi[k];
474  }
475  }
476 
477  // === Graph Filter Process after best reference selection ========
478  Matrix1D<double> ccvec_filt;
479  graphFourierFilter(ccvec,ccvec_filt);
480 
481  // choose best of the candidates after 2nd loop
482  int idx = ccvec.maxIndex();
483 
484  // choose best candidate direction from graph filtered ccvect signal
485  int idxfilt = ccvec_filt.maxIndex();
486 
487  // angular distance between this two directions
488  Matrix1D<double> dirj;
489  Matrix1D<double> dirjp;
490  double sphericalDistance= angDistance(idx, idxfilt, dirj, dirjp);
491 
492  // set output alignment parameters values
493  double rotRef = referenceRot.at(idx);
494  double tiltRef = referenceTilt.at(idx);
495  double shiftX = bestTx2[idx];
496  double shiftY = bestTy2[idx];
497  double anglePsi = bestPsi2[idx];
498  corr = ccvec[idx];
499 
500  //save metadata of images with angles
501  rowOut.setValue(MDL_IMAGE, fnImgOut);
502  rowOut.setValue(MDL_ENABLED, 1);
503  rowOut.setValue(MDL_MAXCC, corr);
504  rowOut.setValue(MDL_ANGLE_ROT, rotRef);
505  rowOut.setValue(MDL_ANGLE_TILT, tiltRef);
506  rowOut.setValue(MDL_ANGLE_PSI, realWRAP(anglePsi, -180., 180.));
507  rowOut.setValue(MDL_SHIFT_X, -shiftX);
508  rowOut.setValue(MDL_SHIFT_Y, -shiftY);
509  rowOut.setValue(MDL_WEIGHT, 1.);
510  rowOut.setValue(MDL_WEIGHT_SIGNIFICANT, 1.);
511  rowOut.setValue(MDL_GRAPH_DISTANCE2MAX, sphericalDistance);
512 
513  // validate angular assignment
514  validateAssignment(idx, idxfilt, rotRef, tiltRef, rowIn, rowOut, MDaIn, dirjp);
515 }
516 
517 double ProgAngularAssignmentMag::angDistance(int &idx, int &idxfilt,
518  Matrix1D<double> &dirj, Matrix1D<double> &dirjp) {
519  double rotj = referenceRot.at(idx);
520  double tiltj = referenceTilt.at(idx);
521  double psij = 0.;
522  Euler_direction(rotj, tiltj, psij, dirj);
523  double rotjp = referenceRot.at(idxfilt);
524  double tiltjp = referenceTilt.at(idxfilt);
525  double psijp = 0.;
526  Euler_direction(rotjp, tiltjp, psijp, dirjp);
527  double sphericalDistance = RAD2DEG(spherical_distance(dirj, dirjp));
528 
529  // compute distance keeping in mind the symmetry list
530  for (size_t sym = 0; sym < SL.symsNo(); sym++) {
531  double auxRot, auxTilt, auxPsi; // equivalent coordinates
532  double auxSphericalDist;
533  Euler_apply_transf(L[sym], R[sym], rotjp, tiltjp, psijp, auxRot,
534  auxTilt, auxPsi);
535  Euler_direction(auxRot, auxTilt, auxPsi, dirjp);
536  auxSphericalDist = RAD2DEG(spherical_distance(dirj, dirjp));
537  if (auxSphericalDist < sphericalDistance)
538  sphericalDistance = auxSphericalDist;
539  }
540  return sphericalDistance;
541 }
542 
543 void ProgAngularAssignmentMag::validateAssignment(int &idx, int &idxfilt, double &rotRef,
544  double &tiltRef, const MDRow &rowIn, MDRow &rowOut,
545  MultidimArray<double> &MDaIn, Matrix1D<double> &dirjp) {
546  if (!useForValidation) {
547  // align & correlation between reference images located at idx and idxfilt
549  double graphCorr = alignImages(vecMDaRef[idx], vecMDaRef[idxfilt], M2,
550  xmipp_transformation::DONT_WRAP);
551  rowOut.setValue(MDL_GRAPH_CC, graphCorr);
552  } else {
553  // assignment in this run
554  // get projection of volume from coordinates computed using my method
555  Projection P2;
556  double initPsiAngle = 0.;
557  projectVolume(refVol(), P2, refYdim, refXdim, rotRef, tiltRef,
558  initPsiAngle);
559  MultidimArray<double> projectedReference2((int) Ydim, (int) Xdim);
560  projectedReference2 = P2();
561 
562  double filtRotRef = referenceRot.at(idxfilt);
563  double filtTiltRef = referenceTilt.at(idxfilt);
564  Projection P3;
565  projectVolume(refVol(), P3, refYdim, refXdim, filtRotRef, filtTiltRef,
566  initPsiAngle);
567  MultidimArray<double> projectedReference3((int) Ydim, (int) Xdim);
568  projectedReference3 = P3();
569 
570  // align & correlation between reference images located at idx and idxfilt
572  double graphCorr = alignImages(projectedReference2, projectedReference3,
573  M2, xmipp_transformation::DONT_WRAP);
574  rowOut.setValue(MDL_GRAPH_CC, graphCorr);
575 
576  // related to previous assignment
577  double old_rot, old_tilt, old_psi, old_shiftX, old_shiftY;
578  rowIn.getValue(MDL_ANGLE_ROT, old_rot);
579  rowIn.getValue(MDL_ANGLE_TILT, old_tilt);
580  rowIn.getValue(MDL_ANGLE_PSI, old_psi);
581  rowIn.getValue(MDL_SHIFT_X, old_shiftX);
582  rowIn.getValue(MDL_SHIFT_Y, old_shiftY);
583 
584  // get projection of volume from this coordinates
585  Projection P;
586  projectVolume(refVol(), P, refYdim, refXdim, old_rot, old_tilt,
587  initPsiAngle);
588  MultidimArray<double> projectedReference((int) Ydim, (int) Xdim);
589  projectedReference = P();
590 
591  // align & correlation between reference images both methods
592  // projectedReference2 is from this assignment
594  projectedReference2 = P2();
595  double refCorr = alignImages(projectedReference, projectedReference2, M,
596  xmipp_transformation::DONT_WRAP);
597 
598  // align & correlation between reference images by previous assignment and idxfilt
599  projectedReference = P();
600  projectedReference3 = P3();
601  graphCorr = alignImages(projectedReference, projectedReference3, M,
602  xmipp_transformation::DONT_WRAP);
603 
604  MultidimArray<double> mdainShifted((int) Ydim, (int) Xdim);
605  mdainShifted.setXmippOrigin();
606  old_psi *= -1;
607  applyShiftAndRotation(MDaIn, old_psi, old_shiftX, old_shiftY,
608  mdainShifted);
609  circularWindow(mdainShifted); //circular masked
610  double prevCorr = correlationIndex(projectedReference, mdainShifted);
611 
612  //angular distance between idxfilt direction and the given by previous alignment
613  Matrix1D<double> dirjpCopy;
614  dirjpCopy = dirjp;
615  Matrix1D<double> dirPrevious;
616  double relPsi = 0.;
617  Euler_direction(old_rot, old_tilt, relPsi, dirPrevious);
618  double algorithmSD = RAD2DEG(
619  spherical_distance(dirjpCopy, dirPrevious));
620 
621  // compute distance keeping in mind the symmetry list
622  for (size_t sym = 0; sym < SL.symsNo(); sym++) {
623  // related to compare against previous assignment
624  double auxRot2, auxTilt2, auxPsi2; // equivalent coordinates
625  double auxSphericalDist2;
626  Euler_apply_transf(L[sym], R[sym], old_rot, old_tilt, relPsi,
627  auxRot2, auxTilt2, auxPsi2);
628  Euler_direction(auxRot2, auxTilt2, auxPsi2, dirPrevious);
629  auxSphericalDist2 = RAD2DEG(
630  spherical_distance(dirPrevious, dirjpCopy));
631  if (auxSphericalDist2 < algorithmSD)
632  algorithmSD = auxSphericalDist2;
633 
634  }
635 
636  rowOut.setValue(MDL_MAXCC_PREVIOUS, prevCorr);
637  rowOut.setValue(MDL_GRAPH_DISTANCE2MAX_PREVIOUS, algorithmSD);
638  rowOut.setValue(MDL_GRAPH_CC_PREVIOUS, graphCorr);
639  rowOut.setValue(MDL_ASSIGNED_DIR_REF_CC, refCorr);
640  }
641 }
642 
644  // from angularContinousAssign2
645  MetaData &ptrMdOut = getOutputMd();
646 
647  ptrMdOut.removeDisabled();
648  double maxCC = -1.;
649  int j = 0;
650  for (size_t objId : ptrMdOut.ids())
651  {
652  double thisMaxCC;
653  ptrMdOut.getValue(MDL_MAXCC, thisMaxCC, objId);
654  if (thisMaxCC > maxCC)
655  maxCC = thisMaxCC;
656  if (thisMaxCC == 0.0)
657  ptrMdOut.removeObject(objId);
658  j++;
659  }
660  for (size_t objId : ptrMdOut.ids())
661  {
662  double thisMaxCC;
663  ptrMdOut.getValue(MDL_MAXCC, thisMaxCC, objId);
664  ptrMdOut.setValue(MDL_WEIGHT, thisMaxCC / maxCC, objId);
665  ptrMdOut.setValue(MDL_WEIGHT_SIGNIFICANT, thisMaxCC / maxCC,
666  objId);
667  }
668  ptrMdOut.write(XmippMetadataProgram::fn_out.replaceExtension("xmd"));
669 }
670 
671 /* cartImg contains cartessian grid representation of image,
672  * rad and ang are the number of radius and angular elements*/
673 MultidimArray<double> ProgAngularAssignmentMag::imToPolar(
674  MultidimArray<double> &cartIm, size_t &start, size_t &end) {
675 
676  size_t thisNbands = end - start;
677  MultidimArray<double> polarImg((int)thisNbands, (int)n_ang2);
678  auto pi = (double)3.141592653;
679  // coordinates of center
680  double cy = (double)(Ydim + (Ydim % 2)) / 2.0; // for odd/even images
681  double cx = (double)(Xdim + (Xdim % 2)) / 2.0;
682 
683  // scale factors
684  double sfy = (double)(Ydim - 1) / 2.0;
685  double sfx = (double)(Xdim - 1) / 2.0;
686 
687  auto delR = 1.0 / ((double)n_rad); // n_rad-1
688  double delT = 2.0 * pi / ((double)n_ang2);
689 
690  // loop through rad and ang coordinates
691  double r;
692  double t;
693  double x_coord;
694  double y_coord;
695  for (size_t ri = start; ri < end; ++ri) {
696  for (size_t ti = 0; ti < n_ang2; ++ti) {
697  r = (double)ri * delR;
698  t = (double)ti * delT;
699  x_coord = (r * cos(t)) * sfx + cx;
700  y_coord = (r * sin(t)) * sfy + cy;
701  // set value of polar img
702  DIRECT_A2D_ELEM(polarImg,ri-start,ti) = interpolate(cartIm,x_coord,y_coord);
703  }
704  }
705  return polarImg;
706 }
707 
708 /* bilinear interpolation */
709 double ProgAngularAssignmentMag::interpolate(MultidimArray<double> &cartIm,
710  double &x_coord, double &y_coord) const{
711  double val;
712  auto xf = (size_t)floor((double)x_coord);
713  auto xc = (size_t)ceil((double)x_coord);
714  auto yf = (size_t)floor((double)y_coord);
715  auto yc = (size_t)ceil((double)y_coord);
716 
717  if ((xf == xc) && (yf == yc)) {
718  val = dAij(cartIm, xc, yc);
719  } else if (xf == xc) { // linear
720  val = dAij(cartIm, xf, yf)
721  + (y_coord - (double) yf)
722  * ( dAij(cartIm, xf, yc) - dAij(cartIm, xf, yf));
723  } else if (yf == yc) { // linear
724  val = dAij(cartIm, xf, yf)
725  + (x_coord - (double) xf)
726  * ( dAij(cartIm, xc, yf) - dAij(cartIm, xf, yf));
727  } else { // bilinear
728  val = ((double) (( dAij(cartIm,xf,yf) * ((double) yc - y_coord)
729  + dAij(cartIm,xf,yc) * (y_coord - (double) yf))
730  * ((double) xc - x_coord))
731  + (double) (( dAij(cartIm,xc,yf) * ((double) yc - y_coord)
732  + dAij(cartIm,xc,yc) * (y_coord - (double) yf))
733  * (x_coord - (double) xf)))
734  / (double) ((xc - xf) * (yc - yf));
735  }
736 
737  return val;
738 }
739 
740 /* implementing centering using circular-shift*/
741 void ProgAngularAssignmentMag::completeFourierShift(const MultidimArray<double> &in,
742  MultidimArray<double> &out) const {
743 
744  // correct output size
745  out.resizeNoCopy(in);
746 
747  auto Cf = (size_t) ((double)YSIZE(in) / 2.0 + 0.5);
748  auto Cc = (size_t) ((double)XSIZE(in) / 2.0 + 0.5);
749 
750  size_t ff;
751  size_t cc;
752  for (size_t f = 0; f < YSIZE(in); f++) {
753  ff = (f + Cf) % YSIZE(in);
754  for (size_t c = 0; c < XSIZE(in); c++) {
755  cc = (c + Cc) % XSIZE(in);
756  DIRECT_A2D_ELEM(out, ff, cc) = DIRECT_A2D_ELEM(in, f, c);
757  }
758  }
759 }
760 
761 /*
762  * experiment for cross-correlation matrix product F1 .* conj(F2)
763  */
764 void ProgAngularAssignmentMag::ccMatrix(const MultidimArray<std::complex<double>> &F1,
765  const MultidimArray<std::complex<double>> &F2,/*reference image*/
766  MultidimArray<double> &result,
767  FourierTransformer &transformer) {
768 
769  result.resizeNoCopy(YSIZE(F1), 2 * (XSIZE(F1) - 1));
770 
771  transformer.setReal(result);
772  transformer.setFourier(F1);
773  // Multiply FFT1 .* FFT2'
774  double a;
775  double b;
776  double c;
777  double d; // a+bi, c+di
778  auto dSize = (double)MULTIDIM_SIZE(result);
779 
780  double *ptrFFT2 = (double*) MULTIDIM_ARRAY(F2);
781  double *ptrFFT1 = (double*) MULTIDIM_ARRAY(transformer.fFourier);
783  {
784  a = (*ptrFFT1)* dSize;
785  b = (*(ptrFFT1 + 1))* dSize;
786  c = (*ptrFFT2++);
787  d = (*ptrFFT2++) * (-1);
788  *ptrFFT1++ = (a * c - b * d);
789  *ptrFFT1++ = (b * c + a * d);
790  }
791  transformer.inverseFourierTransform();
792  CenterFFT(result, true);
793  result.setXmippOrigin();
794 }
795 
796 /* gets maximum value for each column*/
797 void ProgAngularAssignmentMag::maxByColumn(const MultidimArray<double> &in,
798  MultidimArray<double> &out) const {
799 
800  out.resizeNoCopy(1, XSIZE(in));
801  double maxVal;
802  double val2;
803  for (int c = 0; c < XSIZE(in); c++) {
804  maxVal = dAij(in, 0, c);
805  for (int f = 1; f < YSIZE(in); f++) {
806  val2 = dAij(in, f, c);
807  if (val2 > maxVal)
808  maxVal = val2;
809  }
810  dAi(out,c) = maxVal;
811  }
812 }
813 
814 /* gets maximum value for each row */
815 void ProgAngularAssignmentMag::maxByRow(const MultidimArray<double> &in,
816  MultidimArray<double> &out) const {
817  out.resizeNoCopy(1, YSIZE(in));
818  double maxVal;
819  double val2;
820  for (int f = 0; f < YSIZE(in); f++) {
821  maxVal = dAij(in, f, 0);
822  for (int c = 1; c < XSIZE(in); c++) {
823  val2 = dAij(in, f, c);
824  if (val2 > maxVal)
825  maxVal = val2;
826  }
827  dAi(out,f) = maxVal;
828  }
829 }
830 
831 /*quadratic interpolation for location of peak in crossCorr vector*/
832 double quadInterp(/*const*/int idx, const MultidimArray<double> &in) {
833 
834  double InterpIdx = idx - ( ( dAi(in,idx+1) - dAi(in, idx - 1))
835  / ( dAi(in,idx+1) + dAi(in, idx - 1) - 2 * dAi(in, idx)) )
836  / 2.;
837  return InterpIdx;
838 }
839 
840 /* precompute circular 2D window Ydim x Xdim*/
841 void ProgAngularAssignmentMag::computeCircular() {
842 
843  auto Cf = (double)(Ydim + (Ydim % 2)) / 2.0; // for odd/even images
844  auto Cc = (double)(Xdim + (Xdim % 2)) / 2.0;
845  int pixReduc = 1;
846  double rad2 = (Cf - pixReduc) * (Cf - pixReduc);
847  double val = 0;
848 
849  C.resizeNoCopy(Ydim, Xdim);
850  C.initZeros((int)Ydim, (int)Xdim);
852  {
853  val = ((double)j - Cf) * ((double)j - Cf) + ((double)i - Cc) * ((double)i - Cc);
854  if (val < rad2)
855  dAij(C,i,j) = 1.;
856  }
857 }
858 
859 /*apply circular window to input image*/
860 void ProgAngularAssignmentMag::circularWindow(MultidimArray<double> &in) const {
862  {
863  dAij(in,i,j) *= dAij(C, i, j);
864  }
865 }
866 
867 /* Only for 180 angles
868  * just two locations of maximum peaks in ccvRot */
869 void ProgAngularAssignmentMag::psiCandidates(const MultidimArray<double> &in,
870  std::vector<double> &cand, const size_t &size) {
871  double max1 = -1000.;
872  int idx1 = 0;
873  double max2 = -1000.;
874  int idx2 = 0;
875  int cont = 0;
876  peaksFound = cont;
877 
878  for (int i = 89; i < 272; ++i) { // only look within 90:-90 range
879  // current value is a peak value?
880  if ((dAi(in,size_t(i)) > dAi(in, size_t(i - 1)))
881  && (dAi(in,size_t(i)) > dAi(in, size_t(i + 1)))) {
882  if ( dAi(in,i) > max1) {
883  max2 = max1;
884  idx2 = idx1;
885  max1 = dAi(in, i);
886  idx1 = i;
887  cont += 1;
888  } else if ( dAi(in,i) > max2 && dAi(in,i) != max1) {
889  max2 = dAi(in, i);
890  idx2 = i;
891  cont += 1;
892  }
893  }
894  }
895  if (idx1 != 0) {
896  int maxAccepted = 1;
897  std::vector<int> temp;
898  if (idx2 != 0) {
899  maxAccepted = 2;
900  temp.resize(maxAccepted);
901  temp[0] = idx1;
902  temp[1] = idx2;
903  } else {
904  temp.resize(maxAccepted);
905  temp[0] = idx1;
906  }
907 
908  int tam = 2 * maxAccepted;
909  peaksFound = tam;
910  double interpIdx; // quadratic interpolated location of peak
911  for (int i = 0; i < maxAccepted; ++i) {
912  interpIdx = quadInterp(temp[i], in);
913  cand[i] = double(size) / 2. - interpIdx;
914  cand[i + maxAccepted] = (cand[i] >= 0.0) ? cand[i] + 180. : cand[i] - 180.;
915  }
916  } else {
917  peaksFound = 0;
918  }
919 }
920 
921 /* selection of best candidate to rotation and its corresponding shift
922  * shifts are computed as maximum of CrossCorr vector
923  * vector<double> cand contains candidates to relative rotation between images
924  */
925 void ProgAngularAssignmentMag::bestCand(/*inputs*/
926  const MultidimArray<double> &MDaIn,
927  const MultidimArray<std::complex<double> > &MDaInF,
928  const MultidimArray<double> &MDaRef, std::vector<double> &cand,
929  /*outputs*/
930  double &psi, double &shift_x, double &shift_y, double &bestCoeff) {
931  psi = 0;
932  shift_x = 0.;
933  shift_y = 0.;
934  bestCoeff = 0.0;
936 
937  auto workload = [&](int id, int i) {
938  auto rotVar = -1. * cand[i]; //negative, because is for reference rotation
939  MultidimArray<double> MDaRefRot;
940  MDaRefRot.setXmippOrigin();
941  applyRotation(MDaRef, rotVar, MDaRefRot); //rotation to reference image
943  transformersForImages[id].FourierTransform(MDaRefRot, MDaRefRotF, true);
944  auto &ccMatrixShift = ccMatrixShifts.at(id);
945  ccMatrix(MDaInF, MDaRefRotF, ccMatrixShift, ccMatrixBestCandidTransformers.at(id)); // cross-correlation matrix
946 
947  MultidimArray<double> ccVectorTx;
948  maxByColumn(ccMatrixShift, ccVectorTx); // ccvMatrix to ccVector
949  double tx = 0;
950  getShift(ccVectorTx, tx, XSIZE(ccMatrixShift));
951  MultidimArray<double> ccVectorTy;
952  maxByRow(ccMatrixShift, ccVectorTy); // ccvMatrix to ccVector
953  double ty = 0;
954  getShift(ccVectorTy, ty, YSIZE(ccMatrixShift));
955 
956  if (std::abs(tx) > maxShift || std::abs(ty) > maxShift)
957  return;
958 
959  //apply transformation to experimental image
960  double expTx;
961  double expTy;
962  double expPsi;
963  expPsi = -rotVar;
964  // applying in one transform
965  MultidimArray<double> MDaInShiftRot;
966  MDaInShiftRot.setXmippOrigin();
967  applyShiftAndRotation(MDaIn, expPsi, tx, ty, MDaInShiftRot);
968 
969  circularWindow(MDaInShiftRot); //circular masked MDaInRotShift
970 
971  auto tempCoeff = correlationIndex(MDaRef, MDaInShiftRot);
972  std::lock_guard lock(mutex);
973  if (tempCoeff > bestCoeff) {
974  bestCoeff = tempCoeff;
975  shift_x = tx;
976  shift_y = ty;
977  psi = expPsi;
978  }
979  };
980 
981  // process peaks in parallel
982  auto futures = std::vector<std::future<void>>();
983  for (size_t i = 0; i < peaksFound; ++i) {
984  futures.emplace_back(threadPool.push(workload, i));
985  }
986  // wait for processing to finish
987  for (auto &f : futures) {
988  f.get();
989  }
990 }
991 
992 /* apply rotation */
994  MultidimArray<double> &MDaRefRot) const{
995  // Transform matrix
996  Matrix2D<double> A(3, 3);
997  A.initIdentity();
998  double ang = DEG2RAD(rot);
999  double cosine = cos(ang);
1000  double sine = sin(ang);
1001 
1002  // rotation
1003  MAT_ELEM(A,0, 0) = cosine;
1004  MAT_ELEM(A,0, 1) = sine;
1005  MAT_ELEM(A,1, 0) = -sine;
1006  MAT_ELEM(A,1, 1) = cosine;
1007 
1008  // Shift
1009  MAT_ELEM(A,0, 2) = 0.;
1010  MAT_ELEM(A,1, 2) = 0.;
1011 
1012  applyGeometry(xmipp_transformation::LINEAR, MDaRefRot, MDaRef, A, xmipp_transformation::IS_NOT_INV, xmipp_transformation::DONT_WRAP);
1013 }
1014 
1015 /* finds shift as maximum of ccVector */
1016 void ProgAngularAssignmentMag::getShift(MultidimArray<double> &ccVector,
1017  double &shift, const size_t &size) const {
1018  double maxVal = -10.;
1019  int idx = 0;
1020  auto lb = (int)((double)size / 2. - maxShift);
1021  auto hb = (int)((double)size / 2. + maxShift);
1022  for (int i = lb; i < hb; ++i) {
1023  if (( dAi(ccVector,size_t(i)) > dAi(ccVector, size_t(i - 1)))
1024  && ( dAi(ccVector,size_t(i)) > dAi(ccVector, size_t(i + 1))) && // is this value a peak value?
1025  (dAi(ccVector,i) > maxVal)) { // is the biggest?
1026  maxVal = dAi(ccVector, i);
1027  idx = i;
1028  }
1029  }
1030 
1031  if (idx) {
1032  // interpolate value
1033  double interpIdx;
1034  interpIdx = quadInterp(idx, ccVector);
1035  shift = double(size) / 2. - interpIdx;
1036  } else {
1037  shift = maxShift+1.;
1038  }
1039 
1040 }
1041 
1042 /* apply shift then rotation */
1044  double &ty, MultidimArray<double> &MDaRefRot) const {
1045  // Transform matrix
1046  Matrix2D<double> A(3, 3);
1047  A.initIdentity();
1048  double ang = DEG2RAD(rot);
1049  double cosine = cos(ang);
1050  double sine = sin(ang);
1051 
1052  // rotate in opposite direction
1053  double realTx = cosine * tx + sine * ty;
1054  double realTy = -sine * tx + cosine * ty;
1055 
1056  // rotation
1057  MAT_ELEM(A,0, 0) = cosine;
1058  MAT_ELEM(A,0, 1) = sine;
1059  MAT_ELEM(A,1, 0) = -sine;
1060  MAT_ELEM(A,1, 1) = cosine;
1061 
1062  // Shift
1063  MAT_ELEM(A,0, 2) = realTx;
1064  MAT_ELEM(A,1, 2) = realTy;
1065 
1066  applyGeometry(xmipp_transformation::LINEAR, MDaRefRot, MDaRef, A, xmipp_transformation::IS_NOT_INV, xmipp_transformation::DONT_WRAP);
1067 }
#define dAi(v, i)
Mutex mutex
correlation of references assigned by two methods
double spherical_distance(const Matrix1D< double > &r1, const Matrix1D< double > &r2)
Definition: geometry.cpp:73
#define yc
Rotation angle of an image (double,degrees)
#define YSIZE(v)
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
double getDoubleParam(const char *param, int arg=0)
__host__ __device__ float2 floor(const float2 v)
void getMatrices(int i, Matrix2D< double > &L, Matrix2D< double > &R, bool homogeneous=true) const
Definition: symmetries.cpp:348
void inverseFourierTransform()
Definition: xmipp_fftw.cpp:329
void read(const FileName &inFile, const std::vector< MDLabel > *desiredLabels=nullptr, bool decomposeStack=true) override
void transformationMatrix2Parameters2D(const Matrix2D< T > &A, bool &flip, T &scale, T &shiftX, T &shiftY, T &psi)
double alignImages(const MultidimArray< double > &Iref, const AlignmentTransforms &IrefTransforms, MultidimArray< double > &I, Matrix2D< double > &M, bool wrap, AlignmentAux &aux, CorrelationAux &aux2, RotationalCorrelationAux &aux3)
Definition: filters.cpp:2047
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
void computeMinMax(T &minval, T &maxval) const
Definition: matrix1d.cpp:571
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY2D(m)
doublereal * c
#define MULTIDIM_SIZE(v)
void Euler_direction(double alpha, double beta, double gamma, Matrix1D< double > &v)
Definition: geometry.cpp:721
#define DEG2RAD(d)
Definition: xmipp_macros.h:312
void resizeNoCopy(const MultidimArray< T1 > &v)
#define dAij(M, i, j)
auto push(F &&f, Rest &&... rest) -> std::future< decltype(f(0, rest...))>
Definition: ctpl.h:152
MultidimArray< std::complex< double > > fFourier
Definition: xmipp_fftw.h:70
Distance to graph filtered max.
virtual void write(const FileName &outFile, WriteModeMetaData mode=MD_OVERWRITE) const =0
unsigned long long getTotalSystemMemory()
Tilting angle of an image (double,degrees)
int readSymmetryFile(FileName fn_sym, double accuracy=SYM_ACCURACY)
Definition: symmetries.cpp:33
Shift for the image in the X axis (double)
void applyGeometry(int SplineDegree, MultidimArray< std::complex< double > > &V2, const MultidimArray< std::complex< double > > &V1, const Matrix2D< double > &A, bool inv, bool wrap, std::complex< double > outside, MultidimArray< double > *BcoeffsPtr)
There is not enough memory for allocation.
Definition: xmipp_error.h:166
#define DIRECT_A2D_ELEM(v, i, j)
double correlationIndex(const MultidimArray< T > &x, const MultidimArray< T > &y, const MultidimArray< int > *mask=NULL, MultidimArray< double > *Contributions=NULL)
void getImageSize(const MetaData &md, size_t &Xdim, size_t &Ydim, size_t &Zdim, size_t &Ndim, MDLabel image_label)
#define MULTIDIM_ARRAY(v)
void inv(Matrix2D< T > &result) const
Definition: matrix2d.cpp:663
Special label to be used when gathering MDs in MpiMetadataPrograms.
void abs(Image< double > &op)
Matrix2D< T > transpose() const
Definition: matrix2d.cpp:1314
int symsNo() const
Definition: symmetries.h:268
void resize(int nThreads)
Definition: ctpl.h:70
virtual IdIteratorProxy< false > ids()
void Euler_apply_transf(const Matrix2D< double > &L, const Matrix2D< double > &R, double rot, double tilt, double psi, double &newrot, double &newtilt, double &newpsi)
Definition: geometry.cpp:1038
void write(const FileName &fn) const
Definition: matrix1d.cpp:794
virtual bool getValue(MDObject &mdValueOut, size_t id) const =0
when previous assignment validation
size_t size() const override
#define i
Is this image enabled? (int [-1 or 1])
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
doublereal * d
int maxIndex() const
Definition: matrix1d.cpp:610
void resizeNoCopy(int Ydim, int Xdim)
Definition: matrix2d.h:534
double quadInterp(int idx, const MultidimArray< double > &in)
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
void CenterFFT(MultidimArray< T > &v, bool forward)
Definition: xmipp_fft.h:291
void clear()
Definition: matrix2d.h:473
#define M2
doublereal * b
Weight due to Angular significance.
T & getValue(MDLabel label)
void applyShiftAndRotation(const MultidimArray< double > &MDaRef, double &rot, double &tx, double &ty, MultidimArray< double > &MDaRefRot) const
FileName fn_in
Filenames of input and output Metadata.
const char * getParam(const char *param, int arg=0)
void setReal(MultidimArray< double > &img)
Definition: xmipp_fftw.cpp:129
virtual void synchronize()
Synchronize with other processors.
void getCompleteFourier(T &V)
Definition: xmipp_fftw.h:234
int in
double * f
void setFourier(const MultidimArray< std::complex< double > > &imgFourier)
Definition: xmipp_fftw.cpp:249
#define XSIZE(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
void generalizedEigs(const Matrix2D< double > &A, const Matrix2D< double > &B, Matrix1D< double > &D, Matrix2D< double > &P)
Definition: matrix2d.cpp:267
#define ZSIZE(v)
void projectVolume(FourierProjector &projector, Projection &P, int Ydim, int Xdim, double rot, double tilt, double psi, const MultidimArray< double > *ctf)
Maximum cross-correlation for the image (double)
int verbose
Verbosity level.
void initZeros()
Definition: matrix1d.h:592
void FourierTransform(T &v, T1 &V, bool getCopy=true)
Definition: xmipp_fftw.h:166
#define j
Correlation from previous alignment.
bool setValue(const MDLabel label, const T &valueIn, size_t id)
void setValue(MDLabel label, const T &d, bool addLabel=true)
void show() const override
constexpr T MB(T bytes)
Definition: memory_utils.h:87
void processImage(const FileName &fnImg, const FileName &fnImgOut, const MDRow &rowIn, MDRow &rowOut) override
virtual void removeDisabled()
#define RAD2DEG(r)
Definition: xmipp_macros.h:320
void read(const FileName &fn)
Definition: matrix2d.cpp:101
std::string String
Definition: xmipp_strings.h:34
double psi(const double x)
void write(const FileName &fn) const
Definition: matrix2d.cpp:113
String formatString(const char *format,...)
void initZeros()
Definition: matrix2d.h:626
#define realWRAP(x, x0, xF)
Definition: xmipp_macros.h:304
bool checkParam(const char *param)
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false, int mode=WRITE_READONLY)
#define pi
bool each_image_produces_an_output
Indicate that an output is produced for each image in the input.
when previous assignment validation
Shift for the image in the Y axis (double)
void addUsageLine(const char *line, bool verbatim=false)
void initZeros(const MultidimArray< T1 > &op)
int getIntParam(const char *param, int arg=0)
void FFT_magnitude(const MultidimArray< std::complex< double > > &v, MultidimArray< double > &mag)
Definition: xmipp_fftw.cpp:393
Correlation between assigned direction and graph filtered maximum.
virtual bool removeObject(size_t id)=0
Name of an image (std::string)
void resize(size_t Ydim, size_t Xdim, bool noCopy=false)
Definition: matrix2d.cpp:1022
void applyRotation(const MultidimArray< double > &, double &, MultidimArray< double > &) const
bool produces_a_metadata
Indicate that the unique final output file is a Metadata.
doublereal * a
void addParamsLine(const String &line)
void initIdentity()
Definition: matrix2d.h:673
< Score 4 for volumes
#define xc