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

#include <angular_commonline.h>

Collaboration diagram for Prog_Angular_CommonLine:
Collaboration graph
[legend]

Public Member Functions

void read (int argc, const char **argv)
 
void show () const
 
void usage () const
 
void produceSideInfo ()
 
double optimizeGroup (const Matrix1D< int > &imgIdx, Matrix1D< double > &solution, bool show=false)
 
void optimize (Matrix1D< double > &solution)
 
double realignCurrentSolution ()
 
double trySolution (const Matrix1D< double > &solution)
 
double computeClusters (const MultidimArray< double > &correlationMatrix, std::vector< std::vector< int > > &clusters, MultidimArray< double > &worseCorrelationMatrix, MultidimArray< double > &bestCorrelationMatrix, bool show=false) const
 
std::vector< int > removeViaClusters (const MultidimArray< double > &correlationMatrix)
 
void run ()
 

Public Attributes

FileName fnSel
 
FileName fnOut
 
FileName fnSym
 
int NGen
 
int NGroup
 
bool tryInitial
 
MetaDataVec SF
 
EulerSolversolver
 
std::vector< MultidimArray< double > > img
 
Matrix1D< double > initialSolution
 
Matrix1D< int > alreadyOptimized
 
Matrix1D< double > currentSolution
 
Matrix1D< double > currentImgAvgCorrelation
 
Matrix1D< double > currentImgMinCorrelation
 
MultidimArray< double > currentCorrelationMatrix
 
Matrix2D< int > bestLine
 
Matrix2D< double > bestLineCorrelation
 
SymList SL
 
std::vector< std::vector< MultidimArray< double > > > radon
 
std::vector< Matrix2D< double > > L
 
std::vector< Matrix2D< double > > R
 

Detailed Description

Class for running the program

Definition at line 79 of file angular_commonline.h.

Member Function Documentation

◆ computeClusters()

double Prog_Angular_CommonLine::computeClusters ( const MultidimArray< double > &  correlationMatrix,
std::vector< std::vector< int > > &  clusters,
MultidimArray< double > &  worseCorrelationMatrix,
MultidimArray< double > &  bestCorrelationMatrix,
bool  show = false 
) const

Compute clusters

Definition at line 966 of file angular_commonline.cpp.

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 }
#define YSIZE(v)
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
size_t size() const
Definition: matrix1d.h:508
#define i
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
#define FOR_ALL_ELEMENTS_IN_MATRIX1D(v)
Definition: matrix1d.h:72
#define XSIZE(v)
void initZeros()
Definition: matrix1d.h:592
#define XMIPP_MIN(x, y)
Definition: xmipp_macros.h:181
#define j
Matrix1D< int > alreadyOptimized
void initZeros(const MultidimArray< T1 > &op)
int * n

◆ optimize()

void Prog_Angular_CommonLine::optimize ( Matrix1D< double > &  solution)

Optimize all images

Definition at line 551 of file angular_commonline.cpp.

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
598  Matrix1D<int> imgIdx(1);
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);
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;
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 
876  {
877  if (currentImgAvgCorrelation(i)==1)
878  {
879  meanCorr+=currentImgAvgCorrelation(i);
880  stdCorr+=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
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++)
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 }
std::vector< Matrix2D< double > > R
void init_progress_bar(long total)
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
void Euler_direction(double alpha, double beta, double gamma, Matrix1D< double > &v)
Definition: geometry.cpp:721
void sqrt(Image< double > &op)
Matrix1D< double > currentImgMinCorrelation
MultidimArray< double > currentCorrelationMatrix
std::vector< Matrix2D< double > > L
int symsNo() const
Definition: symmetries.h:268
Matrix1D< double > currentSolution
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
size_t size() const override
#define i
Matrix1D< T > transpose() const
Definition: matrix1d.cpp:644
#define FOR_ALL_ELEMENTS_IN_MATRIX1D(v)
Definition: matrix1d.h:72
std::vector< int > removeViaClusters(const MultidimArray< double > &correlationMatrix)
double Euler_distanceBetweenMatrices(const Matrix2D< double > &E1, const Matrix2D< double > &E2)
Definition: geometry.cpp:671
#define XSIZE(v)
void progress_bar(long rlen)
#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
size_t correlations(const Dimensions &d)
Matrix1D< int > alreadyOptimized
TYPE distance(struct Point_T *p, struct Point_T *q)
Definition: point.cpp:28
void initZeros(const MultidimArray< T1 > &op)
double optimizeGroup(const Matrix1D< int > &imgIdx, Matrix1D< double > &solution, bool show=false)
int * n
void indexSort(MultidimArray< int > &indx) const
Matrix1D< double > currentImgAvgCorrelation
T computeMax() const

◆ optimizeGroup()

double Prog_Angular_CommonLine::optimizeGroup ( const Matrix1D< int > &  imgIdx,
Matrix1D< double > &  solution,
bool  show = false 
)

Optimize a single group

Definition at line 473 of file angular_commonline.cpp.

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);
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 }
double Energy() const
Call these functions after Solve() to get results.
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
#define VEC_XSIZE(m)
Definition: matrix1d.h:77
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)
virtual bool Solve(int maxGenerations)
glob_prnt iter
Matrix1D< double > currentSolution
#define i
#define FOR_ALL_ELEMENTS_IN_MATRIX1D(v)
Definition: matrix1d.h:72
double wrapperSolverEnergy(double trial[], void *prm)
constexpr int stBest2Bin
#define ABS(x)
Definition: xmipp_macros.h:142
void Setup(double min[], double max[], int deStrategy, double diffScale, double crossoverProb)
Setup() must be called before solve to set min, max, strategy etc.
void initZeros()
Definition: matrix1d.h:592
double steps
Matrix1D< int > alreadyOptimized
#define MATRIX1D_ARRAY(v)
Definition: matrix1d.h:58
double * Solution(void)
Return best solution.
EulerSolver * global_Eulersolver

◆ produceSideInfo()

void Prog_Angular_CommonLine::produceSideInfo ( )

Produce side info

Definition at line 377 of file angular_commonline.cpp.

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  {
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 }
std::vector< Matrix2D< double > > R
void init_progress_bar(long total)
#define YSIZE(v)
void getMatrices(int i, Matrix2D< double > &L, Matrix2D< double > &R, bool homogeneous=true) const
Definition: symmetries.cpp:348
void read(const FileName &inFile, const std::vector< MDLabel > *desiredLabels=nullptr, bool decomposeStack=true) override
double psi(const size_t n=0) const
std::vector< MultidimArray< double > > img
int readSymmetryFile(FileName fn_sym, double accuracy=SYM_ACCURACY)
Definition: symmetries.cpp:33
std::vector< Matrix2D< double > > L
double correlationIndex(const MultidimArray< T > &x, const MultidimArray< T > &y, const MultidimArray< int > *mask=NULL, MultidimArray< double > *Contributions=NULL)
double rot(const size_t n=0) const
int symsNo() const
Definition: symmetries.h:268
virtual IdIteratorProxy< false > ids()
Matrix1D< double > currentSolution
int readApplyGeo(const FileName &name, const MDRow &row, const ApplyGeoParams &params=DefaultApplyGeoParams)
size_t size() const override
#define i
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
Matrix2D< double > bestLineCorrelation
std::vector< std::vector< MultidimArray< double > > > radon
void resize(size_t Xdim, bool copy=true)
Definition: matrix1d.h:410
void progress_bar(long rlen)
void initZeros()
Definition: matrix1d.h:592
Matrix1D< double > initialSolution
void getRow(size_t i, MultidimArray< T > &v) const
Matrix1D< int > alreadyOptimized
void initZeros()
Definition: matrix2d.h:626
int * n
void resize(size_t Ydim, size_t Xdim, bool noCopy=false)
Definition: matrix2d.cpp:1022

◆ read()

void Prog_Angular_CommonLine::read ( int  argc,
const char **  argv 
)

Read parameters from command line

Definition at line 343 of file angular_commonline.cpp.

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 }
bool checkParameter(int argc, const char **argv, const char *param)
Definition: args.cpp:97
const char * getParameter(int argc, const char **argv, const char *param, const char *option)
Definition: args.cpp:30
int textToInteger(const char *str)

◆ realignCurrentSolution()

double Prog_Angular_CommonLine::realignCurrentSolution ( )

Optimize what we have done so far

Definition at line 1188 of file angular_commonline.cpp.

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();
1195  Matrix1D<int> imgIdx(NToSolve);
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);
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 
1235  delete solver;
1236  return energy;
1237 }
Matrix1D< double > imgAvgCorrelation
Matrix1D< double > currentImgMinCorrelation
MultidimArray< double > currentCorrelationMatrix
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)
glob_prnt iter
Matrix1D< double > currentSolution
#define i
Matrix1D< T > transpose() const
Definition: matrix1d.cpp:644
#define FOR_ALL_ELEMENTS_IN_MATRIX1D(v)
Definition: matrix1d.h:72
double wrapperSolverEnergy(double trial[], void *prm)
double sum(bool average=false) const
Definition: matrix1d.cpp:652
void initZeros()
Definition: matrix1d.h:592
double steps
Matrix1D< int > alreadyOptimized
Matrix1D< double > imgMinCorrelation
MultidimArray< double > correlationMatrix
EulerSolver * global_Eulersolver
Matrix1D< double > currentImgAvgCorrelation

◆ removeViaClusters()

std::vector< int > Prog_Angular_CommonLine::removeViaClusters ( const MultidimArray< double > &  correlationMatrix)

Split the alignment in two clusters and find an image to remove

Definition at line 1128 of file angular_commonline.cpp.

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 }
int * nmax
#define i
double computeClusters(const MultidimArray< double > &correlationMatrix, std::vector< std::vector< int > > &clusters, MultidimArray< double > &worseCorrelationMatrix, MultidimArray< double > &bestCorrelationMatrix, bool show=false) const
Matrix1D< double > currentImgAvgCorrelation

◆ run()

void Prog_Angular_CommonLine::run ( )

Run

Definition at line 1269 of file angular_commonline.cpp.

1270 {
1271  if (tryInitial)
1272  {
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 }
Rotation angle of an image (double,degrees)
double psi(const size_t n=0) const
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)
Special label to be used when gathering MDs in MpiMetadataPrograms.
void write(const FileName &outFile, WriteModeMetaData mode=MD_OVERWRITE) const
double rot(const size_t n=0) const
virtual IdIteratorProxy< false > ids()
Matrix1D< double > currentSolution
int readApplyGeo(const FileName &name, const MDRow &row, const ApplyGeoParams &params=DefaultApplyGeoParams)
double tilt(const size_t n=0) const
void optimize(Matrix1D< double > &solution)
bool setValue(const MDObject &mdValueIn, size_t id)
size_t addObject() override
Matrix1D< double > initialSolution
void setEulerAngles(double rot, double tilt, double psi, const size_t n=0)
double trySolution(const Matrix1D< double > &solution)

◆ show()

void Prog_Angular_CommonLine::show ( ) const

Show parameters

Definition at line 353 of file angular_commonline.cpp.

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 }

◆ trySolution()

double Prog_Angular_CommonLine::trySolution ( const Matrix1D< double > &  solution)

Try a solution

Definition at line 1240 of file angular_commonline.cpp.

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 }
#define VEC_XSIZE(m)
Definition: matrix1d.h:77
double EnergyFunction(double trial[], bool &bAtSolution)
Matrix1D< double > currentSolution
#define i
void setShow(bool newShow)
constexpr int stBest2Bin
void Setup(double min[], double max[], int deStrategy, double diffScale, double crossoverProb)
Setup() must be called before solve to set min, max, strategy etc.
void initZeros()
Definition: matrix1d.h:592
Matrix1D< int > alreadyOptimized
#define MATRIX1D_ARRAY(v)
Definition: matrix1d.h:58
void initConstant(T val)
Definition: matrix1d.cpp:83
MultidimArray< double > correlationMatrix

◆ usage()

void Prog_Angular_CommonLine::usage ( ) const

Usage

Definition at line 364 of file angular_commonline.cpp.

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 }

Member Data Documentation

◆ alreadyOptimized

Matrix1D<int> Prog_Angular_CommonLine::alreadyOptimized

Definition at line 150 of file angular_commonline.h.

◆ bestLine

Matrix2D<int> Prog_Angular_CommonLine::bestLine

Definition at line 166 of file angular_commonline.h.

◆ bestLineCorrelation

Matrix2D<double> Prog_Angular_CommonLine::bestLineCorrelation

Definition at line 169 of file angular_commonline.h.

◆ currentCorrelationMatrix

MultidimArray<double> Prog_Angular_CommonLine::currentCorrelationMatrix

Definition at line 163 of file angular_commonline.h.

◆ currentImgAvgCorrelation

Matrix1D<double> Prog_Angular_CommonLine::currentImgAvgCorrelation

Definition at line 157 of file angular_commonline.h.

◆ currentImgMinCorrelation

Matrix1D<double> Prog_Angular_CommonLine::currentImgMinCorrelation

Definition at line 160 of file angular_commonline.h.

◆ currentSolution

Matrix1D<double> Prog_Angular_CommonLine::currentSolution

Definition at line 154 of file angular_commonline.h.

◆ fnOut

FileName Prog_Angular_CommonLine::fnOut

Output filename

Definition at line 85 of file angular_commonline.h.

◆ fnSel

FileName Prog_Angular_CommonLine::fnSel

Filename of the selfile with the images

Definition at line 82 of file angular_commonline.h.

◆ fnSym

FileName Prog_Angular_CommonLine::fnSym

Symmetry file

Definition at line 88 of file angular_commonline.h.

◆ img

std::vector< MultidimArray<double> > Prog_Angular_CommonLine::img

Definition at line 144 of file angular_commonline.h.

◆ initialSolution

Matrix1D<double> Prog_Angular_CommonLine::initialSolution

Definition at line 147 of file angular_commonline.h.

◆ L

std::vector< Matrix2D<double> > Prog_Angular_CommonLine::L

Definition at line 178 of file angular_commonline.h.

◆ NGen

int Prog_Angular_CommonLine::NGen

Number of generations

Definition at line 91 of file angular_commonline.h.

◆ NGroup

int Prog_Angular_CommonLine::NGroup

Number of images in a group

Definition at line 94 of file angular_commonline.h.

◆ R

std::vector< Matrix2D<double> > Prog_Angular_CommonLine::R

Definition at line 181 of file angular_commonline.h.

◆ radon

std::vector< std::vector< MultidimArray<double> > > Prog_Angular_CommonLine::radon

Definition at line 175 of file angular_commonline.h.

◆ SF

MetaDataVec Prog_Angular_CommonLine::SF

Definition at line 138 of file angular_commonline.h.

◆ SL

SymList Prog_Angular_CommonLine::SL

Definition at line 172 of file angular_commonline.h.

◆ solver

EulerSolver* Prog_Angular_CommonLine::solver

Definition at line 141 of file angular_commonline.h.

◆ tryInitial

bool Prog_Angular_CommonLine::tryInitial

Try initial solution

Definition at line 97 of file angular_commonline.h.


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