Xmipp  v3.23.11-Nereus
angular_commonline.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Carlos Oscar Sanchez Sorzano (coss@cnb.csic.es)
4  *
5  * Universidad San Pablo C.E.U.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  * 02111-1307 USA
21  *
22  * All comments concerning this program package may be sent to the
23  * e-mail address 'xmipp@cnb.csic.es'
24  ***************************************************************************/
25 
26 #include "angular_commonline.h"
27 #include <data/filters.h>
28 #include <core/geometry.h>
29 #include <core/xmipp_image.h>
30 #include <reconstruction/radon.h>
31 
32 /* Constructor ------------------------------------------------------------- */
34  const Matrix1D<int> &newAlreadyOptimized,
35  const Matrix1D<double> &newCurrentSolution,
36  const MultidimArray<int> &newImgIdx,
37  const Prog_Angular_CommonLine *newParent): DESolver(dim, pop)
38 {
39  parent = newParent;
40  Ndim = dim;
41  NToSolve=dim/3;
42  Nimg=VEC_XSIZE(newAlreadyOptimized);
47  alreadyOptimized=&newAlreadyOptimized;
48  currentSolution=&newCurrentSolution;
49  imgIdx=&newImgIdx;
50  show=false;
51 }
52 
53 void EulerSolver::setShow(bool newShow)
54 {
55  show=newShow;
56 }
57 
58 /* Energy function for the solver ------------------------------------------ */
59 double EulerSolver::EnergyFunction(double trial[], bool &bAtSolution)
60 {
61  // Check limits
62  int i,j;
63 
64  for (i=0, j=0; i<Ndim; i++,j=(j+1)%3)
65  {
66  if (j==1)
67  trial[i]=realWRAP(trial[i],0,180);
68  else
69  trial[i]=realWRAP(trial[i],0,360);
70  }
71 
72  // Get number of symmetries
73  int Nsym=parent->L.size();
74 
75  // Evaluate goal function for this trial
76  double retval=0;
77  double Ncomparisons=0;
78  double worseSimilarity=2;
79  int idx;
80  static Matrix1D<int> imgCorrelationN;
81  static double minval=0;
86  imgCorrelationN.initZeros(Nimg);
87  for (int imgi=0; imgi<Nimg; imgi++)
88  {
89  // Get the right angles for this image
90  if ((*alreadyOptimized)(imgi)==0)
91  continue;
92  else if ((*alreadyOptimized)(imgi)==1)
93  {
94  for (idx=0; idx<NToSolve; idx++)
95  if ((*imgIdx)(idx)==imgi)
96  break;
97  idx*=3;
98  /*
99  trial[idx] = parent->initialSolution(3*imgi);
100  trial[idx+1] = parent->initialSolution(3*imgi+1);
101  trial[idx+2] = parent->initialSolution(3*imgi+2);
102  */
103  roti = trial[idx++];
104  tilti = trial[idx++];
105  psii = trial[idx];
106  }
107  else
108  {
109  idx=3*imgi;
110  roti = (*currentSolution)(idx++);
111  tilti = (*currentSolution)(idx++);
112  psii = (*currentSolution)(idx);
113  }
114 
115  // Loop for the second image
116  for (int imgj=imgi+1; imgj<Nimg; imgj++)
117  {
118  // Get the right angles for this image
119  if ((*alreadyOptimized)(imgj)==0)
120  continue;
121  else if ((*alreadyOptimized)(imgj)==1)
122  {
123  for (idx=0; idx<NToSolve; idx++)
124  if ((*imgIdx)(idx)==imgj)
125  break;
126  idx*=3;
127  /*
128  trial[idx] = parent->initialSolution(3*imgj);
129  trial[idx+1] = parent->initialSolution(3*imgj+1);
130  trial[idx+2] = parent->initialSolution(3*imgj+2);
131  */
132  rotj = trial[idx++];
133  tiltj = trial[idx++];
134  psij = trial[idx];
135  }
136  else
137  {
138  idx=3*imgj;
139  rotj = (*currentSolution)(idx++);
140  tiltj = (*currentSolution)(idx++);
141  psij = (*currentSolution)(idx);
142  }
143 
144  // Check that at least one of the two images is new
145  if ((*alreadyOptimized)(imgi)==2 && (*alreadyOptimized)(imgj)==2)
146  continue;
147 
148  double similarity=similarityBetweenTwoLines(imgi,imgj);
149  if (similarity>0)
150  {
151  retval -= similarity;
152  Ncomparisons++;
153  worseSimilarity=XMIPP_MIN(worseSimilarity,similarity);
154  imgAvgCorrelation(imgi)+=similarity;
155  imgAvgCorrelation(imgj)+=similarity;
156  imgMinCorrelation(imgi)=XMIPP_MIN(similarity,
157  imgMinCorrelation(imgi));
158  imgMinCorrelation(imgj)=XMIPP_MIN(similarity,
159  imgMinCorrelation(imgj));
160  correlationMatrix(imgi,imgj)=correlationMatrix(imgj,imgi)=
161  similarity;
162  imgCorrelationN(imgi)++;
163  imgCorrelationN(imgj)++;
164  }
165 
166  double original_rotj=rotj;
167  double original_tiltj=tiltj;
168  double original_psij=psij;
169 
170  for (int sym=0; sym<Nsym; sym++)
171  {
172  Euler_apply_transf(parent->L[sym],parent->R[sym],
173  original_rotj,original_tiltj,original_psij,
174  rotj, tiltj, psij);
175  similarity=similarityBetweenTwoLines(imgi,imgj);
176  if (similarity>0)
177  {
178  retval -= similarity;
179  Ncomparisons++;
180  worseSimilarity=XMIPP_MIN(worseSimilarity,similarity);
181  imgAvgCorrelation(imgi)+=similarity;
182  imgAvgCorrelation(imgj)+=similarity;
183  imgMinCorrelation(imgi)=XMIPP_MIN(similarity,
184  imgMinCorrelation(imgi));
185  imgMinCorrelation(imgj)=XMIPP_MIN(similarity,
186  imgMinCorrelation(imgj));
187  correlationMatrix(imgi,imgj)=correlationMatrix(imgj,imgi)=
188  similarity;
189  imgCorrelationN(imgi)++;
190  imgCorrelationN(imgj)++;
191  }
192  }
193  }
194  }
195  if (Ncomparisons>0)
196  retval/=Ncomparisons;
198  if (imgCorrelationN(i)!=0)
199  imgAvgCorrelation(i)/=imgCorrelationN(i);
200  if (show)
201  std::cout
202  << "Average Distance = " << retval << std::endl
203  << "Worse Distance = " << -worseSimilarity << std::endl
204  << "imgAvgCorrelation = " << imgAvgCorrelation.transpose() << std::endl
205  << "imgMinCorrelation = " << imgMinCorrelation.transpose() << std::endl
206  << std::endl
207  << std::endl
208  ;
209  if (retval<minval)
210  {
211  minval=retval;
212  std::cout << "MinEnergy=" << minval << std::endl;
213  }
214  return retval;
215  // return 0.5*(retval-worseSimilarity);
216 }
217 
218 /* Distance between two common lines --------------------------------------- */
219 //#define DEBUG
220 double EulerSolver::similarityBetweenTwoLines(int imgi, int imgj)
221 {
222  // Compute the direction of the common line in the
223  // universal coordinate system
228  {
229  // They do not share a common line but a common plane
230  if (show)
231  {
232  std::cout
233  << "imgi=" << imgi << " (rot,tilt,psi)=("
234  << roti << "," << tilti << "," << psii << ") normali="
235  << normali.transpose() << std::endl
236  << "imgj=" << imgj << " (rot,tilt,psi)=("
237  << rotj << "," << tiltj << "," << psij << ") normalj="
238  << normalj.transpose() << std::endl
239  ;
240  std::cout << "These two images are taken from the same direction\n";
241  std::cout << "Press any key\n";
242  char c;
243  std::cin >> c;
244  }
245  return -1;
246  }
248 
249  // Compute the direction of the common line in each
250  // of the projection coordinate systems
253 
254  // Compute the angle of the common line in i and j images
255  double angi=RAD2DEG(atan2(YY(commonlinei),XX(commonlinei)));
256  double angj=RAD2DEG(atan2(YY(commonlinej),XX(commonlinej)));
257 
258  auto idxAngi = (int)intWRAP(-((int)angi),0,359);
259  auto idxAngj = (int)intWRAP(-((int)angj),0,359);
260 
261  double retval1=
262  correlationIndex(parent->radon[imgi][idxAngi],
263  parent->radon[imgj][idxAngj]);
264  int idxBesti=parent->bestLine(imgi,imgj);
265  int idxBestj=parent->bestLine(imgj,imgi);
266  int retvali=ABS(idxBesti-idxAngi);
267  if (retvali>180)
268  retvali=ABS(retvali-360);
269  int retvalj=ABS(idxBestj-idxAngj);
270  if (retvalj>180)
271  retvalj=ABS(retvalj-360);
272  retvali=XMIPP_MIN(retvali,10);
273  retvalj=XMIPP_MIN(retvalj,10);
274 
275  const double i180=0.5*1.0/180.0;
276  double retval2=1-(retvali+retvalj)*i180;
277 
278  if (show)
279  {
280  std::cout
281  << "imgi=" << imgi << " (rot,tilt,psi)=("
282  << roti << "," << tilti << "," << psii << ") normali="
283  << normali.transpose() << std::endl
284  << "imgj=" << imgj << " (rot,tilt,psi)=("
285  << rotj << "," << tiltj << "," << psij << ") normalj="
286  << normalj.transpose() << std::endl
287  << "commonline= " << commonline.transpose() << std::endl
288  << "in imgi=" << commonlinei.transpose() << " anglei=" << angi
289  << " (" << idxAngi << ")\n"
290  << "in imgj=" << commonlinej.transpose() << " anglej=" << angj
291  << " (" << idxAngj << ")\n"
292  << "Distance between lines = " << retval1 << " " << retval2
293  << std::endl
294  ;
295  parent->radon[imgi][idxAngi].write("PPPradoni1.txt");
296  parent->radon[imgj][idxAngj].write("PPPradonj1.txt");
297  std::cout << "Press any key\n";
298  char c;
299  std::cin >> c;
300  }
301 
302 #ifdef DEBUG
303  for (idxAngi=0; idxAngi<360; idxAngi++)
304  {
305  double retval3=
306  correlationIndex(parent->radon[imgi][idxAngi],
307  parent->radon[imgj][idxAngj]);
308  ;
309 
310  if (show)
311  {
312  std::cout
313  << " (" << idxAngi << ")\n"
314  << "Distance between lines = " << retval3 << std::endl
315  << std::endl
316  ;
317  parent->radon[imgi][idxAngi].write("PPPradoni2.txt");
318  parent->radon[imgj][idxAngj].write("PPPradonj2.txt");
319  parent->radonDerivative[imgi][idxAngi].write("PPPradonDerivativei2.txt");
320  parent->radonDerivative[imgj][idxAngj].write("PPPradonDerivativej2.txt");
321  std::cout << "Press any key\n";
322  char c;
323  std::cin >> c;
324  if (c=='q')
325  break;
326  }
327  }
328 #endif
329  return retval1*retval2;
330 }
331 #undef DEBUG
332 
333 /* Wrapper for Powell ------------------------------------------------------ */
335 
336 double wrapperSolverEnergy(double trial[], void *prm)
337 {
338  bool bAtSolution;
339  return global_Eulersolver->EnergyFunction(trial+1,bAtSolution);
340 }
341 
342 /* Parameters -------------------------------------------------------------- */
343 void Prog_Angular_CommonLine::read(int argc, const char **argv)
344 {
345  fnSel = getParameter(argc,argv,"-i");
346  fnOut = getParameter(argc,argv,"-oang");
347  fnSym = getParameter(argc,argv,"-sym","");
348  NGen = textToInteger(getParameter(argc,argv,"-NGen","50000"));
349  NGroup = textToInteger(getParameter(argc,argv,"-NGroup","10"));
350  tryInitial = checkParameter(argc,argv,"-tryInitial");
351 }
352 
354 {
355  std::cout << "Selfile: " << fnSel << std::endl
356  << "Output: " << fnOut << std::endl
357  << "Symmetry: " << fnSym << std::endl
358  << "Generations: " << NGen << std::endl
359  << "Groups: " << NGroup << std::endl
360  << "Try Initial: " << tryInitial << std::endl
361  ;
362 }
363 
365 {
366  std::cerr << "angular_commonline\n"
367  << " -i <selfile> : SelFile with input images\n"
368  << " -oang <docfile> : Docfile with the angular assignment\n"
369  << " [-NGen <g=50000>] : Number of generations\n"
370  << " [-NGroup <N=10>] : Number of group comparisons\n"
371  << " [-tryInitial] : Do not optimize\n"
372  << " [-sym <symfile>] : Symmetry\n"
373  ;
374 }
375 
376 /* Produce side info ------------------------------------------------------- */
378 {
379  // Read selfile images and the initial angles
380  SF.read(fnSel);
381  int Nimg=SF.size();
382  initialSolution.resize(3*Nimg);
383  int idx=0;
384  Image<double> I;
385  for (size_t objId : SF.ids())
386  {
387  I.readApplyGeo(SF,objId);
388  img.push_back(I());
389  initialSolution(3*idx)=I.rot();
390  initialSolution(3*idx+1)=I.tilt();
391  initialSolution(3*idx+2)=I.psi();
392  idx++;
393  }
394 
395  // Set current solution
396  // The first image is already optimized and its angles are 0,0,0
397  currentSolution.initZeros(3*Nimg);
399  alreadyOptimized(0)=2;
400 
401  // Symmetry List
402  if (fnSym!="")
403  {
404  SL.readSymmetryFile(fnSym);
405  for (int sym=0; sym<SL.symsNo(); sym++)
406  {
407  Matrix2D<double> auxL, auxR;
408  SL.getMatrices(sym,auxL,auxR);
409  auxL.resize(3,3);
410  auxR.resize(3,3);
411  L.push_back(auxL);
412  R.push_back(auxR);
413  }
414  }
415 
416  // Compute the Radon transform of each image
417  const double deltaRot=1.0;
419  MultidimArray<double> projection;
420  std::cout << "Preprocessing images ...\n";
421  init_progress_bar(Nimg);
422  for (int n=0; n<Nimg; n++)
423  {
424  // Initialize list of projection and derivatives for this image
425  std::vector< MultidimArray<double> > dummyList;
426  radon.push_back(dummyList);
427 
428  // Compute Radon transform of each image
429  Radon_Transform(img[n],deltaRot,RT);
430 
431  // Separate each projection line and compute derivative
432  for (size_t i=0; i<YSIZE(RT); i++)
433  {
434  RT.getRow(i,projection);
435  radon[n].push_back(projection);
436  }
437  progress_bar(n);
438  }
439  progress_bar(Nimg);
440 
441  // Compute the best line in image i that correlates with image j
442  bestLine.initZeros(Nimg,Nimg);
443  bestLineCorrelation.initZeros(Nimg,Nimg);
444  std::cout << "Computing common lines ...\n";
445  init_progress_bar(Nimg);
446  for (int n1=0; n1<Nimg; n1++)
447  {
448  bestLineCorrelation(n1,n1)=1;
449  bestLine(n1,n1)=-1;
450  for (int n2=n1+1; n2<Nimg; n2++)
451  {
452  int lmax=radon[n1].size();
453  for (int l1=0; l1<lmax; l1++)
454  for (int l2=0; l2<lmax; l2++)
455  {
456  double corrl1l2=correlationIndex(radon[n1][l1],
457  radon[n2][l2]);
458  if (corrl1l2>bestLineCorrelation(n1,n2))
459  {
460  bestLineCorrelation(n1,n2)=
461  bestLineCorrelation(n2,n1)=corrl1l2;
462  bestLine(n1,n2)=l1;
463  bestLine(n2,n1)=l2;
464  }
465  }
466  }
467  progress_bar(n1);
468  }
469  progress_bar(Nimg);
470 }
471 
472 /* OptimizeGroup ----------------------------------------------------------- */
474  Matrix1D<double> &solution, bool show)
475 {
476  int count_repetitions = 0;
477  double current_energy = 0;
478  double previous_energy = 2;
479  double first_energy = 2;
480  int NGenStep=NGen/100;
481  int NToSolve=VEC_XSIZE(imgIdx);
482 
483  // Optimize with Differential Evolution
484  // Setup solver
485  Matrix1D<double> minAllowed(3*NToSolve), maxAllowed(3*NToSolve);
486  int idx=0;
487  for (int i=0; i<NToSolve; i++)
488  {
489  maxAllowed(idx++)=360;
490  maxAllowed(idx++)=180;
491  maxAllowed(idx++)=360;
492  }
493  solver=new EulerSolver(3*NToSolve,30*NToSolve,
494  alreadyOptimized, currentSolution, imgIdx, this);
495  solver->Setup(MATRIX1D_ARRAY(minAllowed), MATRIX1D_ARRAY(maxAllowed),
496  stBest2Bin, 0.5, 0.8);
497  global_Eulersolver=solver;
498 
499  // Really optimize
500  bool done = false;
501  int count=0;
502  while (!done)
503  {
504  // Go NGenStep generations ahead
505  solver->Solve(NGenStep);
506  current_energy = solver->Energy();
507  count++;
508 
509  if (current_energy<0 && first_energy>0)
510  first_energy=current_energy;
511 
512  // Check if rather slow convergence
513  if (first_energy<0 &&
514  (ABS((previous_energy-current_energy)/
515  (previous_energy-first_energy)))<0.01)
516  count_repetitions++;
517  else
518  count_repetitions=0;
519 
520  // Show
521  if (show)
522  std::cout << "Iteration: " << count
523  << " Energy: " << current_energy
524  << " ( " << count_repetitions << ")\n";
525 
526 
527  // Stopping criterion
528  if (count_repetitions>=10 && (count>=50 || count==100))
529  done=true;
530 
531  previous_energy = current_energy;
532  }
533 
534  // Optimize with Powell
535  Matrix1D<double> steps(3*NToSolve);
536  steps.initConstant(1);
537 
538  solution.initZeros(steps);
540  VEC_ELEM(solution,i) = solver->Solution()[i];
541  int iter;
542  double retval;
543  powellOptimizer(solution,1,3*NToSolve,wrapperSolverEnergy,nullptr,
544  0.001,retval,iter,steps,show);
545 
546  delete solver;
547  return retval;
548 }
549 
550 /* Optimize ---------------------------------------------------------------- */
552 {
553  size_t Nimg = SF.size();
554  solution.initZeros(3*Nimg);
555  Matrix1D<int> assigned, tabuPenalization;
556  assigned.initZeros(Nimg);
557  assigned(0)=1;
558  tabuPenalization.initZeros(Nimg);
559 
560  // Assign all images
561  int removalCounter=0;
562  while (assigned.sum()<Nimg)
563  {
564  // Initialize the list of Euler vectors
565  // There is a std::vector< Matrix1D<double> > for each image
566  // Each Matrix1D<double> is an orientation found for this image
567  // in an independent experiment
568  std::vector < std::vector< Matrix1D<double> > > eulerAngles;
569  std::vector < std::vector< double > > correlations;
570  eulerAngles.clear();
571  correlations.clear();
572  for (size_t i=0; i<Nimg; i++)
573  {
574  std::vector< Matrix1D<double> > dummy1;
575  std::vector< double > dummy2;
576  eulerAngles.push_back(dummy1);
577  correlations.push_back(dummy2);
578  }
579 
580  // For each image try different pairs and get different alignments
581  std::cout << "Aligning image pairs, "
582  << Nimg-assigned.sum() << " images remaining ...\n";
583  init_progress_bar((int)(Nimg-assigned.sum()));
584  for (size_t i=0; i<Nimg; i++)
585  {
586  if (assigned(i) || tabuPenalization(i)>0)
587  continue;
588  Matrix1D<int> backupAlreadyOptimized=alreadyOptimized;
589 
590  // Perform NGroup experiments
591  for (int n=0; n<NGroup; n++)
592  {
593  // Prepare the vector of images to optimize
594  alreadyOptimized=backupAlreadyOptimized;
595  alreadyOptimized(i)=1;
596 
597  // Align these two images
599  imgIdx(0)=i;
600  Matrix1D<double> auxSolution, anglesi(3);
601  double energy=optimizeGroup(imgIdx,auxSolution,false);
602  anglesi(0)=auxSolution(0);
603  anglesi(1)=auxSolution(1);
604  anglesi(2)=auxSolution(2);
605 
606  // Keep results
607  eulerAngles[i].push_back(anglesi);
608  correlations[i].push_back(-energy);
609  alreadyOptimized=backupAlreadyOptimized;
610  }
611  progress_bar(i);
612  }
613  progress_bar((int)(Nimg-assigned.sum()));
614 
615  // Compute for each image the variance in the top assignment
616  size_t Nsym=SL.symsNo();
617  double bestDistance=-2;
618  int besti=-1;
619  size_t topN=NGroup;
620  for (size_t i=0; i<Nimg; i++)
621  if (eulerAngles[i].size()<2*topN && !assigned(i) &&
622  tabuPenalization(i)==0)
623  topN=(size_t)ceil(eulerAngles[i].size()/2);
624  for (size_t i=0; i<Nimg; i++)
625  {
626  // If the particle has already been assigned skip it
627  if (assigned(i) || tabuPenalization(i)>0)
628  continue;
629 
630  // Sort the images by ascending correlation
632  aux.initZeros(eulerAngles[i].size());
633  for (size_t n=0; n<eulerAngles[i].size(); n++)
634  aux(n)=correlations[i][n];
635  MultidimArray<int> idx;
636  aux.indexSort(idx);
637 
638  // Among the top, compute the distance between
639  // the different Euler angles
640  double distance=0;
641  /*
642  if (topN!=1)
643  {
644  for (int j1=XSIZE(idx)-topN; j1<XSIZE(idx); j1++)
645  {
646  Matrix2D<double> E1;
647  int m=idx(j1)-1;
648  Euler_angles2matrix(eulerAngles[i][m](0),
649  eulerAngles[i][m](1),eulerAngles[i][m](2),E1);
650  for (int j2=j1+1; j2<XSIZE(idx); j2++)
651  {
652  Matrix2D<double> E2;
653  m=idx(j2)-1;
654  double rot=eulerAngles[i][m](0);
655  double tilt=eulerAngles[i][m](1);
656  double psi=eulerAngles[i][m](2);
657  double otherrot, othertilt, otherpsi;
658  Euler_angles2matrix(rot,tilt,psi,E2);
659  double maxDistance=Euler_distanceBetweenMatrices(E1,E2);
660  for (int sym=0; sym<Nsym; sym++)
661  {
662  Euler_apply_transf(L[sym],R[sym],
663  rot, tilt, psi, otherrot, othertilt, otherpsi);
664  Euler_angles2matrix(otherrot,othertilt,otherpsi,E2);
665  double symDistance=Euler_distanceBetweenMatrices(E1,E2);;
666  if (symDistance>maxDistance)
667  maxDistance=symDistance;
668  }
669  distance+=maxDistance;
670  }
671  }
672  distance/=topN*(topN-1)/2.0;
673  }
674  else
675  distance=1.0;
676  */
677  distance=aux.computeMax();
678  std::cout << "Image " << i << " distance=" << distance << " "
679  << " Ncomparisons= " << eulerAngles[i].size()
680  << " topN=" << topN << std::endl;
681  std::cout.flush();
682 
683  if (distance>bestDistance)
684  {
685  bestDistance=distance;
686  besti=i;
687  }
688  }
689 
690  if (bestDistance>0)
691  {
692  // Sort the images by ascending correlation in the best cluster
694  aux.initZeros(eulerAngles[besti].size());
695  for (size_t n=0; n<eulerAngles[besti].size(); n++)
696  aux(n)=correlations[besti][n];
697  MultidimArray<int> idx;
698  aux.indexSort(idx);
699 
700  // Keep only the topN
701  std::vector< Matrix1D<double> > bestEulerAngles;
702  std::vector< double > bestCorrelations;
703  for (size_t n=XSIZE(idx)-topN; n<XSIZE(idx); n++)
704  {
705  bestEulerAngles.push_back(eulerAngles[besti][idx(n)-1]);
706  bestCorrelations.push_back(correlations[besti][idx(n)-1]);
707  }
708 
709  // Show best resolved image
710  std::cout << "Candidates for image " << besti << " distance="
711  << bestDistance << std::endl;
712  for (size_t n=0; n<bestEulerAngles.size(); n++)
713  {
715  Euler_direction(bestEulerAngles[n](0),
716  bestEulerAngles[n](1),bestEulerAngles[n](2),
717  direction);
718  std::cout << bestEulerAngles[n].transpose() << " corr= "
719  << bestCorrelations[n] << " dir= "
720  << direction.transpose() << std::endl;
721  }
722 
723  // Cluster the different solutions
724  std::vector< int > clusterBestAssignment;
725  std::vector< double > clusterBestCorrelation;
726  Matrix1D<int> alreadyClustered;
727  alreadyClustered.initZeros(topN);
728  for (size_t j1=0; j1<topN; j1++)
729  {
730  if (!alreadyClustered(j1))
731  {
732  alreadyClustered(j1)=1;
733 
734  Matrix2D<double> E1;
735  Euler_angles2matrix(bestEulerAngles[j1](0),
736  bestEulerAngles[j1](1),bestEulerAngles[j1](2),
737  E1);
738  double bestCorrelation=bestCorrelations[j1];
739  int bestAssignment=j1;
740  for (size_t j2=j1+1; j2<topN; j2++)
741  {
742  if (!alreadyClustered(j2))
743  {
744  Matrix2D<double> E2;
745  Euler_angles2matrix(bestEulerAngles[j2](0),
746  bestEulerAngles[j2](1),
747  bestEulerAngles[j2](2),E2);
748  double bestCorrE1E2=
750  for (size_t sym=0; sym<Nsym; sym++)
751  {
752  double otherrot, othertilt, otherpsi;
753  Euler_apply_transf(L[sym],R[sym],
754  bestEulerAngles[j2](0), bestEulerAngles[j2](1),
755  bestEulerAngles[j2](2), otherrot, othertilt,
756  otherpsi);
757  Euler_angles2matrix(otherrot,othertilt,otherpsi,E2);
758  double aux=Euler_distanceBetweenMatrices(E1,E2);
759  if (aux>bestCorrE1E2)
760  bestCorrE1E2=aux;
761  }
762  if (bestCorrE1E2>0.97)
763  {
764  alreadyClustered(j2)=1;
765  if (bestCorrelation<bestCorrelations[j2])
766  {
767  bestCorrelation=bestCorrelations[j2];
768  bestAssignment=j2;
769  }
770  }
771  }
772  }
773 
774  clusterBestAssignment.push_back(bestAssignment);
775  clusterBestCorrelation.push_back(bestCorrelation);
776 
777  std::cout << "Cluster headed by "
778  << bestEulerAngles[bestAssignment].transpose()
779  << " corr= " << bestCorrelation << std::endl;
780  }
781  }
782 
783  if (clusterBestAssignment.size()>=5 && assigned.sum()>5)
784  {
785  alreadyOptimized(besti) = 0;
786  assigned(besti) = 0;
787  tabuPenalization(besti)+=10;
788  }
789  else
790  {
791  // Set the status of this image to optimized
792  alreadyOptimized(besti) = 2;
793  assigned(besti) = 1;
794 
795  // Try all the solutions in the cluster just to make sure
796  int bestCluster=-1;
797  double bestEnergy=0;
798  Matrix1D<double> bestCurrentSolution,
799  bestCurrentImgAvgCorrelation,
800  bestCurrentImgMinCorrelation;
801  MultidimArray<double> bestCurrentCorrelationMatrix;
802  if (clusterBestAssignment.size()>1)
803  {
804  Matrix1D<double> backupCurrentSolution;
805  backupCurrentSolution=currentSolution;
806  for (size_t n=0; n<clusterBestAssignment.size(); n++)
807  {
808  std::cout << "Trying solution of cluster " << n << std::endl;
809  currentSolution(3*besti) = bestEulerAngles[
810  clusterBestAssignment[n]](0);
811  currentSolution(3*besti+1) = bestEulerAngles[
812  clusterBestAssignment[n]](1);
813  currentSolution(3*besti+2) = bestEulerAngles[
814  clusterBestAssignment[n]](2);
815  double energy=realignCurrentSolution();
816  if (energy<bestEnergy)
817  {
818  bestEnergy=energy;
819  bestCluster=n;
820  bestCurrentSolution=currentSolution;
821  bestCurrentImgAvgCorrelation=currentImgAvgCorrelation;
822  bestCurrentImgMinCorrelation=currentImgMinCorrelation;
823  bestCurrentCorrelationMatrix=currentCorrelationMatrix;
824  }
825  currentSolution=backupCurrentSolution;
826  }
827  }
828  else
829  {
830  currentSolution(3*besti) = bestEulerAngles[
831  clusterBestAssignment[0]](0);
832  currentSolution(3*besti+1) = bestEulerAngles[
833  clusterBestAssignment[0]](1);
834  currentSolution(3*besti+2) = bestEulerAngles[
835  clusterBestAssignment[0]](2);
836  realignCurrentSolution();
837  bestCluster=0;
838  bestCurrentSolution=currentSolution;
839  bestCurrentImgAvgCorrelation=currentImgAvgCorrelation;
840  bestCurrentImgMinCorrelation=currentImgMinCorrelation;
841  bestCurrentCorrelationMatrix=currentCorrelationMatrix;
842  }
843 
844  // Realign the current solution
845  std::cout << "Cluster chosen " << bestCluster << " angles="
846  << bestEulerAngles[clusterBestAssignment[
847  bestCluster]].transpose() << std::endl;
848  currentSolution=bestCurrentSolution;
849  currentImgAvgCorrelation=bestCurrentImgAvgCorrelation;
850  currentImgMinCorrelation=bestCurrentImgMinCorrelation;
851  currentCorrelationMatrix=bestCurrentCorrelationMatrix;
852  std::cout << "Image Avg Correlation: " << currentImgAvgCorrelation
853  << "\nImage Min Correlation: " << currentImgMinCorrelation
854  << std::endl;
855  }
856 
857  // Cleaning of the "garbage"
858  auto totalAssigned=(int)assigned.sum();
859  std::cout << "removal=" << removalCounter
860  << " totalAssigned=" << totalAssigned
861  << std::endl;
862  removeViaClusters(currentCorrelationMatrix);
863  if (removalCounter!=0 && totalAssigned>3)
864  {
865  std::vector<int> imgsToRemove;
866  int imin=-1;
867  double worseCorrelation=2;
868  double bestCorrelation=-2;
869  if (removalCounter==0)
870  {
871  double meanCorr=0;
872  double stdCorr=0;
873  double Ncorr=0;
874 
875  FOR_ALL_ELEMENTS_IN_MATRIX1D(currentImgAvgCorrelation)
876  {
877  if (currentImgAvgCorrelation(i)==1)
878  {
879  meanCorr+=currentImgAvgCorrelation(i);
880  stdCorr+=currentImgAvgCorrelation(i)*
881  currentImgAvgCorrelation(i);
882  Ncorr++;
883  switch (removalCounter)
884  {
885  case 1:
886  if (currentImgAvgCorrelation(i)<worseCorrelation)
887  {
888  worseCorrelation=currentImgAvgCorrelation(i);
889  imin=i;
890  }
891  break;
892  case 2:
893  if (currentImgAvgCorrelation(i)>bestCorrelation)
894  {
895  bestCorrelation=currentImgAvgCorrelation(i);
896  imin=i;
897  }
898  break;
899  }
900  }
901  }
902  imgsToRemove.push_back(imin);
903  if (Ncorr>0)
904  {
905  meanCorr/=Ncorr;
906  stdCorr=sqrt(stdCorr/Ncorr-meanCorr*meanCorr);
907  std::cout << "Mean=" << meanCorr << " std="
908  << stdCorr << std::endl;
909  if (ABS(worseCorrelation-meanCorr)>3*stdCorr)
910  imgsToRemove.push_back(imin);
911  }
912  }
913  else
914  imgsToRemove=removeViaClusters(currentCorrelationMatrix);
915 
916  if (imgsToRemove.size()!=0)
917  {
918  for (size_t n=0; n<imgsToRemove.size(); n++)
919  {
920  int imin=imgsToRemove[n];
921  std::cout << "Image " << imin << " removed from the "
922  << "current assignment corr="
923  << currentImgAvgCorrelation(imin)
924  << std::endl;
925 
926  alreadyOptimized(imin)=assigned(imin)=0;
927  currentSolution(3*imin)=currentSolution(3*imin+1)=
928  currentSolution(3*imin+2)=0;
929  currentImgAvgCorrelation(imin)=0;
930  currentImgMinCorrelation(imin)=2;
931  for (size_t i=0; i<XSIZE(currentCorrelationMatrix); i++)
932  currentCorrelationMatrix(i,imin)=
933  currentCorrelationMatrix(imin,i)=0;
934  tabuPenalization(imin)+=10;
935  }
936  }
937 
938  }
939  removalCounter=(removalCounter+1)%3;
940  }
941 
942  // Remove one from the penalization of every image
943  FOR_ALL_ELEMENTS_IN_MATRIX1D(tabuPenalization)
944  if (tabuPenalization(i)>0)
945  tabuPenalization(i)--;
946  }
947 
948  solution=currentSolution;
949 }
950 
951 #ifdef NEVERDEFINED
953 {
954  int Nimg = SF.ImgNo();
957  alreadyOptimized(0)=2;
958  Matrix1D<int> imgIdx(Nimg-1);
960  imgIdx(i)=i+1;
961  double energy=optimizeGroup(imgIdx,solution,true);
962 }
963 #endif
964 
965 // Compute clusters
968  std::vector< std::vector<int> > &clusters,
969  MultidimArray<double> &worseCorrelationMatrix,
970  MultidimArray<double> &bestCorrelationMatrix, bool show) const
971 {
972  // Extract the list of images currently optimized and a smaller
973  // correlation matrix
974  std::vector<int> idxImgs;
976  if (alreadyOptimized(i)!=0)
977  idxImgs.push_back(i);
978  int Noptimized=idxImgs.size();
979 
980  // Initially every element is a cluster
981  worseCorrelationMatrix.initZeros(Noptimized,Noptimized);
982  clusters.clear();
983  FOR_ALL_ELEMENTS_IN_ARRAY2D(worseCorrelationMatrix)
984  worseCorrelationMatrix(i,j)=correlationMatrix(idxImgs[i],idxImgs[j]);
985  bestCorrelationMatrix=worseCorrelationMatrix;
986  for (int i=0; i<Noptimized; i++)
987  {
988  std::vector<int> singleElement;
989  singleElement.clear();
990  singleElement.push_back(i);
991  clusters.push_back(singleElement);
992  }
993  std::cout << "Correlation matrix\n"
994  << worseCorrelationMatrix << std::endl;
995 
996  // Compute the average distance between all elements
997  double avgDistance=0;
998  FOR_ALL_ELEMENTS_IN_ARRAY2D(worseCorrelationMatrix)
999  if (i!=j)
1000  avgDistance+=worseCorrelationMatrix(i,j);
1001  else
1002  avgDistance+=1;
1003  avgDistance/=Noptimized*Noptimized;
1004 
1005  // Start the real clustering
1006  while (clusters.size()>2)
1007  {
1008  // Look for the two closest clusters
1009  size_t besti=0, bestj=0;
1010  double bestCorr=-1;
1011  for (size_t i=0; i<YSIZE(worseCorrelationMatrix); i++)
1012  for (size_t j=i+1; j<XSIZE(worseCorrelationMatrix); j++)
1013  if (worseCorrelationMatrix(i,j)>bestCorr)
1014  {
1015  bestCorr=worseCorrelationMatrix(i,j);
1016  besti=i;
1017  bestj=j;
1018  }
1019 
1020  // std::cout << "Joining " << besti << " and " << bestj << std::endl;
1021  // std::cout << "Worse Correlation Matrix:\n" << worseCorrelationMatrix << std::endl;
1022  // std::cout << "Best Correlation Matrix:\n" << bestCorrelationMatrix << std::endl;
1023 
1024  // Join them in the list
1025  for (size_t n=0; n<clusters[bestj].size(); n++)
1026  clusters[besti].push_back(clusters[bestj][n]);
1027  clusters.erase(clusters.begin()+bestj);
1028 
1029  // Readjust the distance between this new cluster and the rest
1030  // of the existing
1031  for (size_t i=0; i<YSIZE(worseCorrelationMatrix); i++)
1032  {
1033  if (i!=besti)
1034  {
1035  worseCorrelationMatrix(besti,i)=
1036  worseCorrelationMatrix(i,besti)=XMIPP_MIN(
1037  worseCorrelationMatrix(i,besti),
1038  worseCorrelationMatrix(i,bestj));
1039  bestCorrelationMatrix(besti,i)=
1040  bestCorrelationMatrix(i,besti)=XMIPP_MAX(
1041  bestCorrelationMatrix(i,besti),
1042  bestCorrelationMatrix(i,bestj));
1043  }
1044  else
1045  {
1046  worseCorrelationMatrix(besti,besti)=
1047  worseCorrelationMatrix(bestj,bestj)=
1048  worseCorrelationMatrix(besti,bestj);
1049  bestCorrelationMatrix(besti,besti)=
1050  bestCorrelationMatrix(bestj,bestj)=
1051  bestCorrelationMatrix(besti,bestj);
1052  }
1053  }
1054 
1055  // Move everything from bestj to the left
1056  for (size_t i=0; i<YSIZE(worseCorrelationMatrix); i++)
1057  for (size_t j=bestj; j<XSIZE(worseCorrelationMatrix)-1; j++)
1058  {
1059  worseCorrelationMatrix(i,j)=worseCorrelationMatrix(i,j+1);
1060  bestCorrelationMatrix(i,j)=bestCorrelationMatrix(i,j+1);
1061  }
1062 
1063  // Move everything from bestj to the top
1064  for (size_t i=bestj; i<YSIZE(worseCorrelationMatrix)-1; i++)
1065  for (size_t j=0; j<XSIZE(worseCorrelationMatrix); j++)
1066  {
1067  worseCorrelationMatrix(i,j)=worseCorrelationMatrix(i+1,j);
1068  bestCorrelationMatrix(i,j)=bestCorrelationMatrix(i+1,j);
1069  }
1070 
1071  // Remove the last row and column of worseCorrelation
1072  worseCorrelationMatrix.resize(YSIZE(worseCorrelationMatrix)-1,
1073  XSIZE(worseCorrelationMatrix)-1);
1074  bestCorrelationMatrix.resize(YSIZE(bestCorrelationMatrix)-1,
1075  XSIZE(bestCorrelationMatrix)-1);
1076  }
1077 
1078  // Substitute the cluster indexes by image indexes
1079  for (size_t n=0; n<2; n++)
1080  for (size_t i=0;i<clusters[n].size(); i++)
1081  clusters[n][i]=idxImgs[clusters[n][i]];
1082 
1083  // Compute the separability
1084  Matrix1D<double> avgDistancek;
1085  avgDistancek.initZeros(2);
1086  for (size_t n=0; n<2; n++)
1087  {
1088  for (size_t i=0;i<clusters[n].size(); i++)
1089  for (size_t j=0;j<clusters[n].size(); j++)
1090  if (i!=j)
1091  avgDistancek(n)+=correlationMatrix(
1092  clusters[n][i],clusters[n][j]);
1093  else
1094  avgDistancek(n)+=1;
1095  avgDistancek(n)/=clusters[n].size()*clusters[n].size();
1096  }
1097  double mergeDistance1=avgDistance/(0.5*(avgDistancek(0)+avgDistancek(1)));
1098  double mergeDistance2;
1099  if (worseCorrelationMatrix(0,0)>0 && worseCorrelationMatrix(1,1)>0)
1100  mergeDistance2=worseCorrelationMatrix(0,1)/
1101  (0.5*(avgDistancek(0)+avgDistancek(1)));
1102  else
1103  mergeDistance2=0;
1104 
1105  if (show)
1106  {
1107  for (int n=0; n<2; n++)
1108  {
1109  std::cout << "Cluster " << n << ": ";
1110  for (size_t i=0;i<clusters[n].size(); i++)
1111  std::cout << clusters[n][i] << " ";
1112  std::cout << std::endl;
1113  }
1114  std::cout << "Merge distance=" << mergeDistance1 << " ="
1115  << avgDistance << "/(0.5*(" << avgDistancek(0) << "+"
1116  << avgDistancek(1) << ")\n";
1117  std::cout << "Merge distance=" << mergeDistance2 << " ="
1118  << worseCorrelationMatrix(0,1) << "/(0.5*("
1119  << avgDistancek(0) << "+"
1120  << avgDistancek(1) << ")\n";
1121  std::cout << "Worse Correlation matrix\n" << worseCorrelationMatrix << std::endl;
1122  std::cout << "Best Correlation matrix\n" << bestCorrelationMatrix << std::endl;
1123  }
1124  return mergeDistance2;
1125 }
1126 
1127 // Performs a HCA to see which image to remove
1130 {
1131  std::vector<int> retval;
1132  std::vector< std::vector<int> > clusters;
1133  MultidimArray<double> worseCorrelationMatrix;
1134  MultidimArray<double> bestCorrelationMatrix;
1135  computeClusters(correlationMatrix,clusters,
1136  worseCorrelationMatrix, bestCorrelationMatrix, true);
1137  if (clusters[0].size()+clusters[1].size()<=4)
1138  return retval;
1139 
1140  // Find the less populated cluster
1141  int nmin=0;
1142  int nmax=1;
1143  if (clusters[0].size()>clusters[1].size())
1144  {
1145  nmin=1;
1146  nmax=0;
1147  }
1148 
1149  // Choose the element or elements to remove
1150  double diameter0=(bestCorrelationMatrix(0,0)-worseCorrelationMatrix(0,0));
1151  double diameter1=(bestCorrelationMatrix(1,1)-worseCorrelationMatrix(1,1));
1152  double diameter01=(bestCorrelationMatrix(0,1)-worseCorrelationMatrix(0,1));
1153  bool separated=(diameter01>(diameter0+diameter1));
1154 
1155  if (separated && clusters[nmin].size()<=3 && clusters[nmax].size()>=6)
1156  {
1157  for (size_t i=0;i<clusters[nmin].size(); i++)
1158  {
1159  int imin=clusters[nmin][i];
1160  retval.push_back(imin);
1161  }
1162  }
1163  else if (clusters[nmax].size()>=4 && clusters[nmin].size()>=3)
1164  {
1165  // Look for the worse image within this cluster
1166  int imin=-1;
1167  double worseCorrelation=2;
1168  for (size_t i=0;i<clusters[nmin].size(); i++)
1169  {
1170  int imgIndex=clusters[nmin][i];
1171  if (currentImgAvgCorrelation(imgIndex)<worseCorrelation)
1172  {
1173  worseCorrelation=currentImgAvgCorrelation(imgIndex);
1174  imin=imgIndex;
1175  }
1176  }
1177  retval.push_back(imin);
1178  }
1179 
1180  // Return which image to remove
1181  std::cout << "Remove images: ";
1182  for (size_t i=0; i< retval.size(); i++)
1183  std::cout << retval[i] << " ";
1184  std::cout << std::endl;
1185  return retval;
1186 }
1187 
1189 {
1190  // Realign all images that have already been optimized
1192  if (alreadyOptimized(i)==2)
1193  alreadyOptimized(i)=1;
1194  auto NToSolve=(int)alreadyOptimized.sum();
1196  int idx=0;
1198  if (alreadyOptimized(i)==1)
1199  imgIdx(idx++)=i;
1200 
1201  solver=new EulerSolver(3*NToSolve,30*NToSolve,
1202  alreadyOptimized, currentSolution, imgIdx, this);
1203  global_Eulersolver=solver;
1204 
1205  Matrix1D<double> steps(3*NToSolve), solution;
1206  steps.initConstant(1);
1207  solution.initZeros(steps);
1208  idx=0;
1210  {
1211  solution(idx++)=currentSolution(3*imgIdx(i));
1212  solution(idx++)=currentSolution(3*imgIdx(i)+1);
1213  solution(idx++)=currentSolution(3*imgIdx(i)+2);
1214  }
1215  int iter;
1216  double energy;
1217  powellOptimizer(solution,1,3*NToSolve,wrapperSolverEnergy,nullptr,
1218  0.001,energy,iter,steps,true);
1219 
1220  idx=0;
1222  {
1223  currentSolution(3*imgIdx(i)) = solution(idx++);
1224  currentSolution(3*imgIdx(i)+1) = solution(idx++);
1225  currentSolution(3*imgIdx(i)+2) = solution(idx++);
1226  }
1227 
1229  if (alreadyOptimized(i)==1)
1230  alreadyOptimized(i)=2;
1231 
1232  currentImgAvgCorrelation=solver->imgAvgCorrelation.transpose();
1233  currentImgMinCorrelation=solver->imgMinCorrelation.transpose();
1234  currentCorrelationMatrix=solver->correlationMatrix;
1235  delete solver;
1236  return energy;
1237 }
1238 
1239 /* Try solution ------------------------------------------------------------ */
1241 {
1242  Matrix1D<double> minAllowed(VEC_XSIZE(solution)), maxAllowed(VEC_XSIZE(solution));
1243  int idx=0;
1244  int Nimg=VEC_XSIZE(solution)/3;
1245  for (int i=0; i<Nimg; i++)
1246  {
1247  maxAllowed(idx++)=360;
1248  maxAllowed(idx++)=180;
1249  maxAllowed(idx++)=360;
1250  }
1251 
1254  MultidimArray<int> imgIdx(Nimg);
1255  imgIdx.initLinear(0,Nimg-1,1,"incr");
1256  bool bAtSolution;
1257  solver=new EulerSolver(VEC_XSIZE(solution),1,
1258  alreadyOptimized,currentSolution,imgIdx,this);
1259  solver->Setup(MATRIX1D_ARRAY(minAllowed), MATRIX1D_ARRAY(maxAllowed),
1260  stBest2Bin, 0.5, 0.8);
1261  solver->setShow(true);
1262  double energy=solver->EnergyFunction(MATRIX1D_ARRAY(solution),bAtSolution);
1263  std::cout << "Correlation matrix\n" << solver->correlationMatrix
1264  << std::endl;
1265  return energy;
1266 }
1267 
1268 /* Run -------------------------------------------------------------------- */
1270 {
1271  if (tryInitial)
1272  {
1273  trySolution(initialSolution);
1274  }
1275  else
1276  {
1277  // Look for the solution
1278  Matrix1D<double> solution;
1279  optimize(solution);
1280 
1281  MetaDataVec DF;
1282 
1283  int idx=0;
1284  Image<double> I;
1285  size_t id;
1286  for (size_t objId : SF.ids())
1287  {
1288  I.readApplyGeo(SF,objId);
1290  currentSolution(idx+2));
1291  idx+=3;
1292  I.write();
1293 
1294  id=DF.addObject();
1295  DF.setValue(MDL_ANGLE_ROT,I.rot(),id);
1296  DF.setValue(MDL_ANGLE_TILT,I.tilt(),id);
1297  DF.setValue(MDL_ANGLE_PSI,I.psi(),id);
1298  }
1299  DF.write(fnOut);
1300  }
1301 }
std::vector< Matrix2D< double > > R
bool checkParameter(int argc, const char **argv, const char *param)
Definition: args.cpp:97
void init_progress_bar(long total)
int * nmax
Rotation angle of an image (double,degrees)
#define YSIZE(v)
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
const Prog_Angular_CommonLine * parent
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
#define XMIPP_MAX(x, y)
Definition: xmipp_macros.h:193
double module() const
Definition: matrix1d.h:983
Matrix1D< double > imgAvgCorrelation
double psi(const size_t n=0) const
size_t size() const
Definition: matrix1d.h:508
#define VEC_XSIZE(m)
Definition: matrix1d.h:77
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
doublereal * c
void Euler_direction(double alpha, double beta, double gamma, Matrix1D< double > &v)
Definition: geometry.cpp:721
void sqrt(Image< double > &op)
Tilting angle of an image (double,degrees)
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)
std::vector< Matrix2D< double > > L
const MultidimArray< int > * imgIdx
double correlationIndex(const MultidimArray< T > &x, const MultidimArray< T > &y, const MultidimArray< int > *mask=NULL, MultidimArray< double > *Contributions=NULL)
Matrix1D< double > commonlinei
Matrix1D< double > normali
double similarityBetweenTwoLines(int imgi, int imgj)
Special label to be used when gathering MDs in MpiMetadataPrograms.
void write(const FileName &outFile, WriteModeMetaData mode=MD_OVERWRITE) const
double EnergyFunction(double trial[], bool &bAtSolution)
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)
void selfNormalize()
Definition: matrix1d.cpp:723
Matrix1D< T > vectorProduct(const Matrix1D< T > &v1, const Matrix1D< T > &v2)
Definition: matrix1d.h:1165
double rot(const size_t n=0) const
glob_prnt iter
Matrix1D< double > normalj
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
int readApplyGeo(const FileName &name, const MDRow &row, const ApplyGeoParams &params=DefaultApplyGeoParams)
#define i
const Matrix1D< double > * currentSolution
void setShow(bool newShow)
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
Matrix1D< T > transpose() const
Definition: matrix1d.cpp:644
void initLinear(T minF, T maxF, int n=1, const String &mode="incr")
double tilt(const size_t n=0) const
void Radon_Transform(const MultidimArray< double > &vol, double rot, double tilt, MultidimArray< double > &RT)
Definition: radon.cpp:30
#define FOR_ALL_ELEMENTS_IN_MATRIX1D(v)
Definition: matrix1d.h:72
void optimize(Matrix1D< double > &solution)
const char * getParameter(int argc, const char **argv, const char *param, const char *option)
Definition: args.cpp:30
#define XX(v)
Definition: matrix1d.h:85
bool setValue(const MDObject &mdValueIn, size_t id)
size_t addObject() override
void read(int argc, const char **argv)
FileName fnOut
std::vector< int > removeViaClusters(const MultidimArray< double > &correlationMatrix)
#define XMIPP_EQUAL_ACCURACY
Definition: xmipp_macros.h:119
double Euler_distanceBetweenMatrices(const Matrix2D< double > &E1, const Matrix2D< double > &E2)
Definition: geometry.cpp:671
double wrapperSolverEnergy(double trial[], void *prm)
std::vector< std::vector< MultidimArray< double > > > radon
#define XSIZE(v)
void progress_bar(long rlen)
constexpr int stBest2Bin
#define ABS(x)
Definition: xmipp_macros.h:142
double sum(bool average=false) const
Definition: matrix1d.cpp:652
void direction(const MultidimArray< double > &orMap, MultidimArray< double > &qualityMap, double lambda, int size, MultidimArray< double > &dirMap, int x, int y)
void initZeros()
Definition: matrix1d.h:592
Matrix1D< double > commonline
double bestEnergy
#define XMIPP_MIN(x, y)
Definition: xmipp_macros.h:181
#define j
void getRow(size_t i, MultidimArray< T > &v) const
size_t correlations(const Dimensions &d)
double steps
#define YY(v)
Definition: matrix1d.h:93
void setEulerAngles(double rot, double tilt, double psi, const size_t n=0)
TYPE distance(struct Point_T *p, struct Point_T *q)
Definition: point.cpp:28
double trySolution(const Matrix1D< double > &solution)
#define MATRIX1D_ARRAY(v)
Definition: matrix1d.h:58
#define RAD2DEG(r)
Definition: xmipp_macros.h:320
Matrix1D< double > imgMinCorrelation
const Matrix1D< int > * alreadyOptimized
EulerSolver(int dim, int pop, const Matrix1D< int > &newAlreadyOptimized, const Matrix1D< double > &newCurrentSolution, const MultidimArray< int > &newImgIdx, const Prog_Angular_CommonLine *newParent)
int textToInteger(const char *str)
#define realWRAP(x, x0, xF)
Definition: xmipp_macros.h:304
ProgClassifyCL2D * prm
Matrix1D< double > commonlinej
double computeClusters(const MultidimArray< double > &correlationMatrix, std::vector< std::vector< int > > &clusters, MultidimArray< double > &worseCorrelationMatrix, MultidimArray< double > &bestCorrelationMatrix, bool show=false) const
void initZeros(const MultidimArray< T1 > &op)
double optimizeGroup(const Matrix1D< int > &imgIdx, Matrix1D< double > &solution, bool show=false)
void Uproject_to_plane(const Matrix1D< double > &point, const Matrix1D< double > &direction, double distance, Matrix1D< double > &result)
Definition: geometry.cpp:39
void initConstant(T val)
Definition: matrix1d.cpp:83
MultidimArray< double > correlationMatrix
int * n
void resize(size_t Ydim, size_t Xdim, bool noCopy=false)
Definition: matrix2d.cpp:1022
#define intWRAP(x, x0, xF)
Definition: xmipp_macros.h:272
EulerSolver * global_Eulersolver
void indexSort(MultidimArray< int > &indx) const
T computeMax() const
void pop(struct stack_T *stack)
Definition: stack.cpp:59