Xmipp  v3.23.11-Nereus
Public Member Functions | Static Public Member Functions | Public Attributes | List of all members

#include <angular_distance.h>

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

Public Member Functions

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

Static Public Member Functions

static void euler2quat (double rot, double tilt, double psi, double q[4])
 
static void quat2Euler (const double q[4], double &rot, double &tilt, double &psi)
 
static void computeAverageAngles (double rot1, double tilt1, double psi1, double rot2, double tilt2, double psi2, double &rot, double &tilt, double &psi)
 
static void computeAverageShifts (double shiftX1, double shiftY1, double shiftX2, double shiftY2, double &shiftX, double &shiftY)
 

Public Attributes

FileName fn_ang1
 
FileName fn_ang2
 
FileName fn_sym
 
FileName fn_out
 
bool check_mirrors
 
bool object_rotation
 
bool compute_weights
 
double minSigma
 
double minSigmaD
 
String idLabel
 
int set
 Set of angular difference. More...
 
int ang
 The set of angles to be used for output. More...
 
bool compute_average_angle
 Compute angle mean. More...
 
bool compute_average_shift
 Compute shift mean. More...
 
MetaDataVec DF1
 
MetaDataVec DF2
 
SymList SL
 
- Public Attributes inherited from XmippProgram
bool doRun
 
bool runWithoutArgs
 
int verbose
 Verbosity level. More...
 
int debug
 

Additional Inherited Members

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

Detailed Description

Angular Distance parameters.

Definition at line 37 of file angular_distance.h.

Member Function Documentation

◆ computeAverageAngles()

void ProgAngularDistance::computeAverageAngles ( double  rot1,
double  tilt1,
double  psi1,
double  rot2,
double  tilt2,
double  psi2,
double &  rot,
double &  tilt,
double &  psi 
)
static

Definition at line 709 of file angular_distance.cpp.

712 {
713  // Convert the angles to quaternions
714  Matrix1D<double> eigvals;
715  Matrix2D<double> quaternions(2, 4), m, eigvecs;
716  euler2quat(rot1, tilt1, psi1, &MAT_ELEM(quaternions, 0, 0));
717  euler2quat(rot2, tilt2, psi2, &MAT_ELEM(quaternions, 1, 0));
718 
719  // Average quaternions into a matrix
720  matrixOperation_AtA(quaternions, m);
721  m /= 2;
722 
723  // Compute the largest eigenvector
724  firstEigs(m, 1UL, eigvals, eigvecs, true);
725 
726  // Convert back to euler. As eigvecs has a single
727  // column it is safe to take a pointer to its data
728  assert(MAT_SIZE(eigvecs) == 4);
729  quat2Euler(MATRIX2D_ARRAY(eigvecs), rot, tilt, psi);
730 }
#define MAT_SIZE(m)
Definition: matrix2d.h:128
static void euler2quat(double rot, double tilt, double psi, double q[4])
void matrixOperation_AtA(const Matrix2D< double > &A, Matrix2D< double > &B)
Definition: matrix2d.cpp:436
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
void firstEigs(const Matrix2D< double > &A, size_t M, Matrix1D< double > &D, Matrix2D< double > &P, bool Pneeded)
Definition: matrix2d.cpp:284
static void quat2Euler(const double q[4], double &rot, double &tilt, double &psi)
int m
double psi(const double x)
#define MATRIX2D_ARRAY(m)
Definition: matrix2d.h:89

◆ computeAverageShifts()

void ProgAngularDistance::computeAverageShifts ( double  shiftX1,
double  shiftY1,
double  shiftX2,
double  shiftY2,
double &  shiftX,
double &  shiftY 
)
static

Definition at line 732 of file angular_distance.cpp.

735 {
736  shiftX = (shiftX1 + shiftX2) / 2;
737  shiftY = (shiftY1 + shiftY2) / 2;
738 }

◆ computeWeights()

void ProgAngularDistance::computeWeights ( )

computeWeights

Definition at line 344 of file angular_distance.cpp.

345 {
346  MetaDataVec DF1sorted, DF2sorted, DFweights;
348  DF1sorted.sort(DF1,label);
349  DF2sorted.sort(DF2,label);
350  std::vector<MDLabel> labels;
351  labels.push_back(label);
352  labels.push_back(MDL_ANGLE_ROT);
353  labels.push_back(MDL_ANGLE_TILT);
354  labels.push_back(MDL_ANGLE_PSI);
355  labels.push_back(MDL_SHIFT_X);
356  labels.push_back(MDL_SHIFT_Y);
357  labels.push_back(MDL_FLIP);
358  DF1sorted.keepLabels(labels);
359  DF2sorted.keepLabels(labels);
360  MDLabel angleDiffLabel, shiftDiffLabel, weightLabel;
361  switch (set)
362  {
363  case 1:
364  angleDiffLabel=MDL_ANGLE_DIFF;
365  shiftDiffLabel=MDL_SHIFT_DIFF;
366  weightLabel=MDL_WEIGHT_JUMPER;
367  break;
368  case 2:
369  angleDiffLabel=MDL_ANGLE_DIFF2;
370  shiftDiffLabel=MDL_SHIFT_DIFF2;
371  weightLabel=MDL_WEIGHT_JUMPER2;
372  break;
373  case 0:
374  angleDiffLabel=MDL_ANGLE_DIFF0;
375  shiftDiffLabel=MDL_SHIFT_DIFF0;
376  weightLabel=MDL_WEIGHT_JUMPER0;
377  break;
378  default:
379  REPORT_ERROR(ERR_VALUE_INCORRECT, "Set value is out of range. It shoudl be 0, 1 or 2.\n");
380  }
381 
382  auto iter1(DF1sorted.ids().begin());
383  auto iter2(DF2sorted.ids().begin());
384  std::vector< Matrix1D<double> > ang1, ang2;
385  Matrix1D<double> rotTiltPsi(5);
386  size_t currentId;
387  bool anotherImageIn2 = iter2 != DF2sorted.ids().end();
388  size_t id1, id2;
389  bool mirror;
390  while (anotherImageIn2)
391  {
392  ang1.clear();
393  ang2.clear();
394 
395  // Take current id
396  DF2sorted.getValue(label,currentId, *iter2);
397 
398  // Grab all the angles in DF2 associated to this id
399  bool anotherIteration=false;
400  do
401  {
402  DF2sorted.getValue(label,id2,*iter2);
403  anotherIteration=false;
404  if (id2==currentId)
405  {
406  DF2sorted.getValue(MDL_ANGLE_ROT,XX(rotTiltPsi),*iter2);
407  DF2sorted.getValue(MDL_ANGLE_TILT,YY(rotTiltPsi),*iter2);
408  DF2sorted.getValue(MDL_ANGLE_PSI,ZZ(rotTiltPsi),*iter2);
409  DF2sorted.getValue(MDL_SHIFT_X,VEC_ELEM(rotTiltPsi,3),*iter2);
410  DF2sorted.getValue(MDL_SHIFT_Y,VEC_ELEM(rotTiltPsi,4),*iter2);
411  DF2sorted.getValue(MDL_FLIP,mirror,*iter2);
412  if (mirror)
413  {
414  double rotp, tiltp, psip;
415  Euler_mirrorY(XX(rotTiltPsi),YY(rotTiltPsi),ZZ(rotTiltPsi), rotp, tiltp, psip);
416  XX(rotTiltPsi)=rotp;
417  YY(rotTiltPsi)=tiltp;
418  ZZ(rotTiltPsi)=psip;
419  }
420  ang2.push_back(rotTiltPsi);
421  ++iter2;
422  if (iter2 != DF2sorted.ids().end())
423  anotherIteration=true;
424  }
425  } while (anotherIteration);
426 
427  // Advance Iter 1 to catch Iter 2
428  double N=0, cumulatedDistance=0, cumulatedDistanceShift=0;
429  size_t newObjId=0;
430  if (iter1 != DF1sorted.ids().end() && *iter1 > 0)
431  {
432  DF1sorted.getValue(label,id1,*iter1);
433  const auto lastID = DF1sorted.ids().end();
434  while (id1<currentId && iter1 != lastID)
435  {
436  ++iter1;
437  if (iter1 != DF1sorted.ids().end())
438  DF1sorted.getValue(label,id1,*iter1);
439  }
440 
441  // If we are at the end of DF1, then we did not find id1 such that id1==currentId
442  if (iter1 == DF1sorted.ids().end())
443  break;
444 
445  // Grab all the angles in DF1 associated to this id
446  anotherIteration=false;
447  do
448  {
449  DF1sorted.getValue(label,id1,*iter1);
450  anotherIteration=false;
451  if (id1==currentId)
452  {
453  DF1sorted.getValue(MDL_ANGLE_ROT,XX(rotTiltPsi),*iter1);
454  DF1sorted.getValue(MDL_ANGLE_TILT,YY(rotTiltPsi),*iter1);
455  DF1sorted.getValue(MDL_ANGLE_PSI,ZZ(rotTiltPsi),*iter1);
456  DF1sorted.getValue(MDL_SHIFT_X,VEC_ELEM(rotTiltPsi,3),*iter1);
457  DF1sorted.getValue(MDL_SHIFT_Y,VEC_ELEM(rotTiltPsi,4),*iter1);
458  DF1sorted.getValue(MDL_FLIP,mirror,*iter1);
459  if (mirror)
460  {
461  double rotp, tiltp, psip;
462  Euler_mirrorY(XX(rotTiltPsi),YY(rotTiltPsi),ZZ(rotTiltPsi), rotp, tiltp, psip);
463  XX(rotTiltPsi)=rotp;
464  YY(rotTiltPsi)=tiltp;
465  ZZ(rotTiltPsi)=psip;
466  }
467  ang1.push_back(rotTiltPsi);
468  ++iter1;
469  if (iter1 != DF1sorted.ids().end())
470  anotherIteration=true;
471  }
472  } while (anotherIteration);
473 
474  // Process both sets of angles
475  cumulatedDistance=0;
476  N=0;
477  for (size_t i=0; i<ang2.size(); ++i)
478  {
479  const Matrix1D<double> &anglesi=ang2[i];
480  double rot2=XX(anglesi);
481  double tilt2=YY(anglesi);
482  double psi2=ZZ(anglesi);
483  double bestDistance=1e38, bestShiftDistance=1e38;
484  for (size_t j=0; j<ang1.size(); ++j)
485  {
486  const Matrix1D<double> &anglesj=ang1[j];
487  double rot1=XX(anglesj);
488  double tilt1=YY(anglesj);
489  double psi1=ZZ(anglesj);
490  double dist = SL.computeDistance(rot1, tilt1, psi1, rot2, tilt2, psi2, false,
492  if (dist<bestDistance)
493  {
494  bestDistance=dist;
495  bestShiftDistance=fabs(VEC_ELEM(anglesi,3)-VEC_ELEM(anglesj,3))+fabs(VEC_ELEM(anglesi,4)-VEC_ELEM(anglesj,4));
496  }
497  }
498  bestShiftDistance*=0.5;
499  if (bestDistance<360)
500  {
501  cumulatedDistance+=bestDistance;
502  cumulatedDistanceShift+=bestShiftDistance;
503  N++;
504  }
505  }
506  newObjId=DFweights.addObject();
507  DFweights.setValue(label,currentId,newObjId);
508  }
509  else
510  N=0;
511 
512  if (N>0)
513  {
514  double meanDistance=cumulatedDistance/ang2.size();
515  DFweights.setValue(angleDiffLabel,meanDistance,newObjId);
516  double meanDistanceShift=cumulatedDistanceShift/ang2.size();
517  DFweights.setValue(shiftDiffLabel,meanDistanceShift,newObjId);
518  ang1.clear();
519  ang2.clear();
520  }
521  else
522  if (newObjId>0)
523  {
524  DFweights.setValue(angleDiffLabel,-1.0,newObjId);
525  DFweights.setValue(shiftDiffLabel,-1.0,newObjId);
526  ang1.clear();
527  ang2.clear();
528  }
529  anotherImageIn2 = iter2 != DF2sorted.ids().end();
530  }
531  if (ang2.size()>0)
532  {
533  size_t newObjId=DFweights.addObject();
534  DFweights.setValue(label,currentId,newObjId);
535  DFweights.setValue(angleDiffLabel,-1.0,newObjId);
536  DFweights.setValue(shiftDiffLabel,-1.0,newObjId);
537  }
538 
539  // If there are more images in MD1 than in MD2, set the last images to 0
540  const auto totalSize = DF2sorted.ids().end();
541  while (iter2 != totalSize)
542  {
543  size_t newObjId=DFweights.addObject();
544  DFweights.setValue(label,currentId,newObjId);
545  DFweights.setValue(angleDiffLabel,-1.0,newObjId);
546  DFweights.setValue(shiftDiffLabel,-1.0,newObjId);
547  ++iter2;
548  }
549 
550  // Calculate the deviation with respect to angleDiff=0 of the angular distances
551  std::vector<double> angleDistances, shiftDistances;
552  DFweights.getColumnValues(angleDiffLabel,angleDistances);
553  DFweights.getColumnValues(shiftDiffLabel,shiftDistances);
554 
555  double sigma2=0, sigma2D=0, N=0;
556  for (size_t i=0; i<angleDistances.size(); ++i)
557  {
558  double d=angleDistances[i];
559  if (d>0)
560  {
561  sigma2+=d*d;
562  d=shiftDistances[i];
563  sigma2D+=d*d;
564  ++N;
565  }
566  }
567  sigma2/=N;
568  sigma2=std::max(minSigma*minSigma,sigma2);
569  std::cout << "Sigma of angular distances=" << sqrt(sigma2) << std::endl;
570  sigma2D/=N;
571  sigma2D=std::max(minSigmaD*minSigmaD,sigma2D);
572  std::cout << "Sigma of shift distances=" << sqrt(sigma2D) << std::endl;
573 
574  // Adjust the jumper weights according to a Gaussian
575  double isigma2=-0.5/sigma2;
576  double isigma2D=-0.5/sigma2D;
577 
578  for (size_t objId : DFweights.ids())
579  {
580  double d;
581  double weight=1.0;
582  DFweights.getValue(angleDiffLabel,d,objId);
583  if (d>0)
584  weight=exp(d*d*isigma2);
585  else
586  weight=0.5;
587 
588  if (minSigmaD>0)
589  {
590  DFweights.getValue(shiftDiffLabel,d,objId);
591  if (d>0)
592  weight*=exp(d*d*isigma2D);
593  else
594  weight*=0.5;
595  }
596  DFweights.setValue(weightLabel,weight,objId);
597  }
598 
599  // Transfer these weights to the DF2 metadata
600  MetaDataDb DF2weighted;
601  if (DF2.containsLabel(angleDiffLabel))
602  DF2.removeLabel(angleDiffLabel);
603  if (DF2.containsLabel(angleDiffLabel))
604  DF2.removeLabel(angleDiffLabel);
605  if (DF2.containsLabel(weightLabel))
606  DF2.removeLabel(weightLabel);
607  DF2weighted.join1(MetaDataDb(DF2),MetaDataDb(DFweights),label,INNER);
608 
609  for (size_t objId : DF2weighted.ids())
610  {
611  double d;
612  DF2weighted.getValue(angleDiffLabel,d,objId);
613  if (d<0)
614  {
615  // DF2weighted.setValue(MDL_ENABLED,-1,objId);
616  DF2weighted.setValue(angleDiffLabel,0.0,objId);
617  }
618  DF2weighted.getValue(shiftDiffLabel,d,objId);
619  if (d<0)
620  {
621  // DF2weighted.setValue(MDL_ENABLED,-1,objId);
622  DF2weighted.setValue(shiftDiffLabel,0.0,objId);
623  }
624  }
625  DF2weighted.removeDisabled();
626  DF2weighted.write(fn_out+"_weights.xmd");
627 }
Rotation angle of an image (double,degrees)
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
shift difference (double)
void sort(const MetaDataVec &MDin, const MDLabel sortLabel, bool asc=true, int limit=-1, int offset=0)
static MDLabel str2Label(const String &labelName)
Weight due to angular jumping.
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
void keepLabels(const std::vector< MDLabel > &labels)
void sqrt(Image< double > &op)
bool removeLabel(const MDLabel label) override
bool getValue(MDObject &mdValueOut, size_t id) const override
Tilting angle of an image (double,degrees)
difference between two angles (double,degrees)
Shift for the image in the X axis (double)
void Euler_mirrorY(double rot, double tilt, double psi, double &newrot, double &newtilt, double &newpsi)
Definition: geometry.cpp:1011
Special label to be used when gathering MDs in MpiMetadataPrograms.
virtual IdIteratorProxy< false > ids()
#define i
doublereal * d
double computeDistance(double rot1, double tilt1, double psi1, double &rot2, double &tilt2, double &psi2, bool projdir_mode, bool check_mirrors, bool object_rotation=false, bool write_mirrors=true)
shift difference (double)
#define XX(v)
Definition: matrix1d.h:85
bool setValue(const MDObject &mdValueIn, size_t id)
Weight due to angular jumping.
size_t addObject() override
Flip the image? (bool)
void max(Image< double > &op1, const Image< double > &op2)
void write(const FileName &outFile, WriteModeMetaData mode=MD_OVERWRITE) const override
#define j
difference between two angles (double,degrees)
#define YY(v)
Definition: matrix1d.h:93
int label
Label.
Definition: micrograph.h:58
bool getValue(MDObject &mdValueOut, size_t id) const override
void getColumnValues(const MDLabel label, std::vector< MDObject > &valuesOut) const override
bool setValue(const MDObject &mdValueIn, size_t id) override
Definition: metadata_db.cpp:90
virtual void removeDisabled()
difference between two angles (double,degrees)
void join1(const MetaDataDb &mdInLeft, const MetaDataDb &mdInRight, const MDLabel label, JoinType type=LEFT)
Weight due to angular jumping.
Shift for the image in the Y axis (double)
bool containsLabel(const MDLabel label) const override
shift difference (double)
Incorrect value received.
Definition: xmipp_error.h:195
#define ZZ(v)
Definition: matrix1d.h:101
MDLabel

◆ defineParams()

void ProgAngularDistance::defineParams ( )
virtual

Define parameters.

Reimplemented from XmippProgram.

Definition at line 79 of file angular_distance.cpp.

80 {
81  addUsageLine("Computes the angular distance between two angle files. The angular distance ");
82  addUsageLine("is defined as the average angular distance between the 3 vectors of the ");
83  addUsageLine("coordinate system defined by the Euler angles (taking into account any ");
84  addUsageLine("possible symmetry). ");
85  addParamsLine(" --ang1 <Metadata1> : Angular document file 1");
86  addParamsLine(" --ang2 <Metadata2> : Angular document file 2");
87  addParamsLine(" [--oroot <rootname=\"\">] : Output rootname");
88  addParamsLine(" : rootname.xmd Angular comparison;");
89  addParamsLine(" : rootname_vec_diff_hist.txt Histogram of the differences in vector directions;");
90  addParamsLine(" : rootname_shift_diff_hist.txt Histogram of the differences in shifts;");
91  addParamsLine(" :+ rootname_rot_diff_hist.txt (verbose>=2) Histogram of the differences in rot;");
92  addParamsLine(" :+ rootname_tilt_diff_hist.txt (verbose>=2) Histogram of the differences in tilt;");
93  addParamsLine(" :+ rootname_psi_diff_hist.txt (verbose>=2) Histogram of the differences in psi;");
94  addParamsLine(" :+ rootname_X_diff_hist.txt (verbose>=2) Histogram of the differences in shiftX;");
95  addParamsLine(" :+ rootname_Y_diff_hist.txt (verbose>=2) Histogram of the differences in shiftY;");
96  addParamsLine(" [--sym <symmetry=\"\">] : Symmetry file if any");
97  addParamsLine(" :+The definition of the symmetry is described at [[transform_symmetrize_v3][transform_symmetrize]]");
98  addParamsLine(" [--check_mirrors] : Check if mirrored projections give better results");
99  addParamsLine(" [--object_rotation] : Use object rotations rather than projection directions");
100  addParamsLine(" : fit (Spider, APMQ)");
101  addParamsLine(" [--compute_weights <minSigma=1> <idLabel=particleId> <minSigmaD=-1>] : If this flag is given, images in ang2 are given a weight according to their ");
102  addParamsLine(" : distance to the same image in ang1. The ang2 file is rewritten.");
103  addParamsLine(" : Ang1 and ang2 are supposed to have a label called itemId");
104  addParamsLine(" : The output is written to oroot+_weights.xmd");
105  addParamsLine(" : Min sigma is the minimum angular standard deviation, by default, 1 degree");
106  addParamsLine(" : Min sigmaD is the minimum shift standard deviation, set to -1 for not using shifts for weighting");
107  addParamsLine(" [--set <set=1>] : Set of distance to compute (angular_diff0 and jumper_weight0, angular_diff and jumper_weight,");
108  addParamsLine(" : or angular_diff2 and jumper_weight2)");
109  addParamsLine(" [--ang <ang=1>] : The angle set to be written in the first position. Note that ang2 may be modified");
110  addParamsLine(" : so that for the given symmetry is the closest to ang1. Therefore using ang=2 is useful ");
111  addParamsLine(" : to obtain get ang2 close to ang1");
112  addParamsLine(" [--compute_average_angle] : Average the angles defined in ang1 and ang2");
113  addParamsLine(" [--compute_average_shift] : Average the shifts defined in ang1 and ang2");
114 }
void addUsageLine(const char *line, bool verbatim=false)
void addParamsLine(const String &line)

◆ euler2quat()

void ProgAngularDistance::euler2quat ( double  rot,
double  tilt,
double  psi,
double  q[4] 
)
static

Definition at line 629 of file angular_distance.cpp.

631 {
632  // Convert to radians and divide by 2
633  const double ai = -DEG2RAD(rot) / 2;
634  const double aj = DEG2RAD(tilt) / 2;
635  const double ak = -DEG2RAD(psi) / 2;
636 
637  // Obtain sin and cos
638  const double si = std::sin(ai),
639  ci = std::cos(ai),
640  sj = std::sin(aj),
641  cj = std::cos(aj),
642  sk = std::sin(ak),
643  ck = std::cos(ak);
644 
645  const double cc = ci * ck,
646  cs = ci * sk,
647  sc = si * ck,
648  ss = si * sk;
649 
650  // Compute the quaternion values
651  // WXYZ
652  q[0] = +cj * (cc - ss);
653  q[1] = +sj * (cs - sc);
654  q[2] = -sj * (cc + ss);
655  q[3] = +cj * (cs + sc);
656 }
#define DEG2RAD(d)
Definition: xmipp_macros.h:312
struct _constraint * cs
double psi(const double x)

◆ produce_side_info()

void ProgAngularDistance::produce_side_info ( )

Produce side info. Read all document files and symmetry list if any. An exception is thrown if both files are not of the same length.

Definition at line 117 of file angular_distance.cpp.

118 {
119  if (fn_sym != "")
121 
122  // Check that both docfiles are of the same length
123  if (fn_ang1!="" && fn_ang2!="")
124  {
125  DF1.read(fn_ang1);
126  DF2.read(fn_ang2);
127  if (DF1.size() != DF2.size() && !compute_weights)
129  "Angular_distance: Input Docfiles with different number of entries");
130  }
131 }
void read(const FileName &inFile, const std::vector< MDLabel > *desiredLabels=nullptr, bool decomposeStack=true) override
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
int readSymmetryFile(FileName fn_sym, double accuracy=SYM_ACCURACY)
Definition: symmetries.cpp:33
size_t size() const override
Incorrect number of objects in Metadata.
Definition: xmipp_error.h:160

◆ quat2Euler()

void ProgAngularDistance::quat2Euler ( const double  q[4],
double &  rot,
double &  tilt,
double &  psi 
)
static

Definition at line 658 of file angular_distance.cpp.

660 {
661  // Multiply the quaternion by sqrt2 to avoid multiplying pairs by 2
662  const auto sqrt2 = std::sqrt(2);
663  const auto qw = sqrt2 * q[0];
664  const auto qx = sqrt2 * q[1];
665  const auto qy = sqrt2 * q[2];
666  const auto qz = sqrt2 * q[3];
667 
668  // Obtain pairwise products of the quaternion elements
669  const auto qx2 = qx*qx;
670  const auto qy2 = qy*qy;
671  const auto qz2 = qz*qz;
672  const auto qxqy = qx*qy;
673  const auto qxqz = qx*qz;
674  const auto qxqw = qx*qw;
675  const auto qyqz = qy*qz;
676  const auto qyqw = qy*qw;
677  const auto qzqw = qz*qw;
678 
679  // Ensemble the matrix
680  const double //m00 = 1 - qy2 - qz2,
681  //m01 = qxqy - qzqw,
682  m02 = qxqz + qyqw,
683  m10 = qxqy + qzqw,
684  m11 = 1 - qx2 - qz2,
685  m12 = qyqz - qxqw,
686  m20 = qxqz - qyqw,
687  m21 = qyqz + qxqw,
688  m22 = 1 - qx2 - qy2;
689 
690 
691 
692  const auto sy = std::sqrt(m21*m21 + m20*m20);
693  double ax, ay, az;
694  if(sy > 1e-6) {
695  ax = std::atan2(m21, m20);
696  ay = std::atan2(sy, m22);
697  az = std::atan2(m12, -m02);
698  } else {
699  ax = std::atan2(-m10, m11);
700  ay = std::atan2(sy, m22);
701  az = 0;
702  }
703 
704  rot = RAD2DEG(ax);
705  tilt = RAD2DEG(ay);
706  psi = RAD2DEG(az);
707 }
void sqrt(Image< double > &op)
#define RAD2DEG(r)
Definition: xmipp_macros.h:320
double psi(const double x)

◆ readParams()

void ProgAngularDistance::readParams ( )
virtual

Read argument from command line.

Reimplemented from XmippProgram.

Definition at line 36 of file angular_distance.cpp.

37 {
38  fn_ang1 = getParam("--ang1");
39  fn_ang2 = getParam("--ang2");
40  fn_out = getParam("--oroot");
41  fn_sym = getParam("--sym");
42  check_mirrors = checkParam("--check_mirrors");
43  object_rotation = checkParam("--object_rotation");
44  compute_weights = checkParam("--compute_weights");
45  if (compute_weights)
46  {
47  minSigma = getDoubleParam("--compute_weights");
48  idLabel = getParam("--compute_weights",1);
49  minSigmaD = getDoubleParam("--compute_weights",2);
50  }
51  set = getIntParam("--set");
52  ang = getIntParam("--ang");
53  compute_average_angle = checkParam("--compute_average_angle");
54  compute_average_shift = checkParam("--compute_average_shift");
55 }
double getDoubleParam(const char *param, int arg=0)
bool compute_average_angle
Compute angle mean.
const char * getParam(const char *param, int arg=0)
bool compute_average_shift
Compute shift mean.
bool checkParam(const char *param)
int ang
The set of angles to be used for output.
int getIntParam(const char *param, int arg=0)

◆ run()

void ProgAngularDistance::run ( )
virtual

Run

Reimplemented from XmippProgram.

Definition at line 135 of file angular_distance.cpp.

136 {
138  if (compute_weights)
139  {
140  computeWeights();
141  return;
142  }
143 
144  MetaDataVec DF_out;
145  double angular_distance=0;
146  double shift_distance=0;
147 
148  MultidimArray<double> rot_diff, tilt_diff, psi_diff, vec_diff,
149  X_diff, Y_diff, shift_diff;
150  rot_diff.resize(DF1.size());
151  tilt_diff.resize(rot_diff);
152  psi_diff.resize(rot_diff);
153  vec_diff.resize(rot_diff);
154  X_diff.resize(rot_diff);
155  Y_diff.resize(rot_diff);
156  shift_diff.resize(rot_diff);
157 
158  // Build output comment
160 
161  size_t id;
162  FileName fnImg;
163  std::vector<double> output;
164  output.resize(17,0);
165  bool fillOutput=fn_out!="";
166 
167  auto iter1(DF1.ids().begin());
168  auto iter2(DF2.ids().begin());
169  const auto s = std::min(DF1.size(), DF2.size());
170  int i;
171  for (i = 0; i < s; ++i, ++iter1, ++iter2)
172  {
173  // Read input data
174  size_t itemId;
175  double rot1, tilt1, psi1;
176  double rot2, tilt2, psi2;
177  double rot2p, tilt2p, psi2p;
178  double distp;
179  double X1, X2, Y1, Y2;
180  DF1.getValue(MDL_ITEM_ID,itemId, *iter1);
181  DF1.getValue(MDL_IMAGE,fnImg, *iter1);
182 
183  DF1.getValue(MDL_ANGLE_ROT,rot1, *iter1);
184  DF1.getValue(MDL_ANGLE_TILT,tilt1, *iter1);
185  DF1.getValue(MDL_ANGLE_PSI,psi1, *iter1);
186  DF1.getValue(MDL_SHIFT_X,X1, *iter1);
187  DF1.getValue(MDL_SHIFT_Y,Y1, *iter1);
188 
189  DF2.getValue(MDL_ANGLE_ROT,rot2, *iter2);
190  DF2.getValue(MDL_ANGLE_TILT,tilt2, *iter2);
191  DF2.getValue(MDL_ANGLE_PSI,psi2, *iter2);
192  DF2.getValue(MDL_SHIFT_X,X2, *iter2);
193  DF2.getValue(MDL_SHIFT_Y,Y2, *iter2);
194 
195  // Bring both angles to a normalized set
196  rot1 = realWRAP(rot1, -180, 180);
197  tilt1 = realWRAP(tilt1, -180, 180);
198  psi1 = realWRAP(psi1, -180, 180);
199 
200  rot2 = realWRAP(rot2, -180, 180);
201  tilt2 = realWRAP(tilt2, -180, 180);
202  psi2 = realWRAP(psi2, -180, 180);
203 
204  // Apply rotations to find the minimum distance angles
205  rot2p = rot2;
206  tilt2p = tilt2;
207  psi2p = psi2;
208  distp = SL.computeDistance(rot1, tilt1, psi1,
209  rot2p, tilt2p, psi2p, false,
211  angular_distance += distp;
212 
213  // Compute angular difference
214  rot_diff(i) = rot1 - rot2p;
215  tilt_diff(i) = tilt1 - tilt2p;
216  psi_diff(i) = psi1 - psi2p;
217  vec_diff(i) = distp;
218  X_diff(i) = X1 - X2;
219  Y_diff(i) = Y1 - Y2;
220  shift_diff(i) = sqrt(X_diff(i)*X_diff(i)+Y_diff(i)*Y_diff(i));
221  shift_distance += shift_diff(i);
222 
223  // Fill the output result
224  if (fillOutput)
225  {
226  MDRowVec row;
227  row.setValue(MDL_ITEM_ID, itemId);
228 
229  // Write angles
231  // Average angles
232  double rotAvg, tiltAvg, psiAvg;
233  computeAverageAngles(rot1, tilt1, psi1,
234  rot2p, tilt2p, psi2p,
235  rotAvg, tiltAvg, psiAvg );
236 
237  row.setValue(MDL_ANGLE_ROT, rotAvg);
238  row.setValue(MDL_ANGLE_ROT2, rot1);
239  row.setValue(MDL_ANGLE_ROT3, rot2p);
240  row.setValue(MDL_ANGLE_TILT, tiltAvg);
241  row.setValue(MDL_ANGLE_TILT2, tilt1);
242  row.setValue(MDL_ANGLE_TILT3, tilt2p);
243  row.setValue(MDL_ANGLE_PSI, psiAvg);
244  row.setValue(MDL_ANGLE_PSI2, psi1);
245  row.setValue(MDL_ANGLE_PSI3, psi2p);
246  } else if (ang==2) {
247  row.setValue(MDL_ANGLE_ROT, rot2p);
248  row.setValue(MDL_ANGLE_ROT2, rot1);
249  row.setValue(MDL_ANGLE_TILT, tilt2p);
250  row.setValue(MDL_ANGLE_TILT2, tilt1);
251  row.setValue(MDL_ANGLE_PSI, psi2p);
252  row.setValue(MDL_ANGLE_PSI2, psi1);
253  } else {
254  row.setValue(MDL_ANGLE_ROT, rot1);
255  row.setValue(MDL_ANGLE_ROT2, rot2p);
256  row.setValue(MDL_ANGLE_TILT, tilt1);
257  row.setValue(MDL_ANGLE_TILT2, tilt2p);
258  row.setValue(MDL_ANGLE_PSI, psi1);
259  row.setValue(MDL_ANGLE_PSI2, psi2p);
260  }
261 
262  // Write angle differences
263  row.setValue(MDL_ANGLE_ROT_DIFF, rot_diff(i));
264  row.setValue(MDL_ANGLE_TILT_DIFF,tilt_diff(i) );
265  row.setValue(MDL_ANGLE_PSI_DIFF, psi_diff(i));
266  if (set==1)
267  row.setValue(MDL_ANGLE_DIFF, distp);
268  else
269  row.setValue(MDL_ANGLE_DIFF2, distp);
270 
271  // Write shifts
273  // Compute average
274  double XAvg, YAvg;
275  computeAverageShifts(X1, Y1,
276  X2, Y2,
277  XAvg, YAvg );
278 
279  row.setValue(MDL_SHIFT_X, XAvg);
280  row.setValue(MDL_SHIFT_X2, X1);
281  row.setValue(MDL_SHIFT_X3, X2);
282  row.setValue(MDL_SHIFT_Y, YAvg);
283  row.setValue(MDL_SHIFT_Y2, Y1);
284  row.setValue(MDL_SHIFT_Y3, Y2);
285  } else if(ang==2) {
286  row.setValue(MDL_SHIFT_X, X2);
287  row.setValue(MDL_SHIFT_X2, X1);
288  row.setValue(MDL_SHIFT_Y, Y2);
289  row.setValue(MDL_SHIFT_Y2, Y1);
290  } else {
291  row.setValue(MDL_SHIFT_X, X1);
292  row.setValue(MDL_SHIFT_X2, X2);
293  row.setValue(MDL_SHIFT_Y, Y1);
294  row.setValue(MDL_SHIFT_Y2, Y2);
295  }
296 
297  // Write shift differences
298  row.setValue(MDL_SHIFT_X_DIFF, X_diff(i));
299  row.setValue(MDL_SHIFT_Y_DIFF, Y_diff(i));
300  if (set==1)
301  row.setValue(MDL_SHIFT_DIFF,shift_diff(i));
302  else
303  row.setValue(MDL_SHIFT_DIFF2,shift_diff(i));
304 
305  id = DF_out.addRow(row);
306  //id = DF_out.addObject();
307  DF_out.setValue(MDL_IMAGE,fnImg,id);
308  //DF_out.setValue(MDL_ANGLE_COMPARISON,output, id);
309  }
310  }
311  if (0 == i) {
312  REPORT_ERROR(ERR_NUMERICAL, "i is zero (0), which would lead to division by zero");
313  }
314  angular_distance /= i;
315  shift_distance /=i;
316 
317  if (fillOutput)
318  {
319  DF_out.write(fn_out + ".xmd");
320  Histogram1D hist;
321  compute_hist(vec_diff, hist, 0, 180, 180);
322  hist.write(fn_out + "_vec_diff_hist.txt",MDL_ANGLE_DIFF,MDL_COUNT);
323  compute_hist(shift_diff, hist, 20);
324  hist.write(fn_out + "_shift_diff_hist.txt",MDL_SHIFT_DIFF,MDL_COUNT);
325  if (verbose==2)
326  {
327  compute_hist(rot_diff, hist, 100);
328  hist.write(fn_out + "_rot_diff_hist.txt");
329  compute_hist(tilt_diff, hist, 100);
330  hist.write(fn_out + "_tilt_diff_hist.txt");
331  compute_hist(psi_diff, hist, 100);
332  hist.write(fn_out + "_psi_diff_hist.txt");
333  compute_hist(X_diff, hist, 20);
334  hist.write(fn_out + "_X_diff_hist.txt");
335  compute_hist(Y_diff, hist, 20);
336  hist.write(fn_out + "_Y_diff_hist.txt");
337  }
338  }
339 
340  std::cout << "Global angular distance = " << angular_distance << std::endl;
341  std::cout << "Global shift distance = " << shift_distance << std::endl;
342 }
Rotation angle of an image (double,degrees)
void min(Image< double > &op1, const Image< double > &op2)
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
Tilting angle of an image (double,degrees)
Shift for the image in the X axis (double)
Shift for the image in the Y axis (double)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
difference between rot angles (double,degrees)
void sqrt(Image< double > &op)
Tilting angle of an image (double,degrees)
void setValue(const MDObject &object) override
Shift for the image in the X axis (double)
Tilting angle of an image (double,degrees)
Special label to be used when gathering MDs in MpiMetadataPrograms.
difference in Shift along Y axis (double)
void write(const FileName &outFile, WriteModeMetaData mode=MD_OVERWRITE) const
virtual IdIteratorProxy< false > ids()
static void computeAverageAngles(double rot1, double tilt1, double psi1, double rot2, double tilt2, double psi2, double &rot, double &tilt, double &psi)
bool compute_average_angle
Compute angle mean.
size_t size() const override
#define i
size_t addRow(const MDRow &row) override
Unique identifier for items inside a list or set (std::size_t)
Shift for the image in the Y axis (double)
Rotation angle of an image (double,degrees)
static void computeAverageShifts(double shiftX1, double shiftY1, double shiftX2, double shiftY2, double &shiftX, double &shiftY)
double computeDistance(double rot1, double tilt1, double psi1, double &rot2, double &tilt2, double &psi2, bool projdir_mode, bool check_mirrors, bool object_rotation=false, bool write_mirrors=true)
shift difference (double)
Number of elements of a type (int) [this is a genereic type do not use to transfer information to ano...
void compute_hist(const MultidimArrayGeneric &array, Histogram1D &hist, int no_steps)
Definition: histogram.cpp:572
difference between psi angles (double,degrees)
bool setValue(const MDObject &mdValueIn, size_t id)
Error related to numerical calculation.
Definition: xmipp_error.h:179
int verbose
Verbosity level.
Psi angle of an image (double,degrees)
difference between two angles (double,degrees)
bool compute_average_shift
Compute shift mean.
bool getValue(MDObject &mdValueOut, size_t id) const override
Shift for the image in the X axis (double)
void write(const FileName &fn, MDLabel=MDL_X, MDLabel=MDL_COUNT)
Definition: histogram.cpp:129
Rotation angle of an image (double,degrees)
#define realWRAP(x, x0, xF)
Definition: xmipp_macros.h:304
difference between two angles (double,degrees)
difference between tilt angles (double,degrees)
Shift for the image in the Y axis (double)
int ang
The set of angles to be used for output.
shift difference (double)
Psi angle of an image (double,degrees)
Name of an image (std::string)
difference in Shift along X axis (double)

◆ show()

void ProgAngularDistance::show ( )

Show.

Definition at line 58 of file angular_distance.cpp.

59 {
60  std::cout
61  << "Angular docfile 1 : " << fn_ang1 << std::endl
62  << "Angular docfile 2 : " << fn_ang2 << std::endl
63  << "Angular output : " << fn_out << std::endl
64  << "Symmetry file : " << fn_sym << std::endl
65  << "Check mirrors : " << check_mirrors << std::endl
66  << "Object rotation : " << object_rotation<<std::endl
67  << "Compute weights : " << compute_weights << std::endl
68  << "Min sigma : " << minSigma << std::endl
69  << "Min sigmaD : " << minSigmaD << std::endl
70  << "IdLabel : " << idLabel << std::endl
71  << "Set : " << set << std::endl
72  << "Ang : " << ang << std::endl
73  << "Compute average angle: " << compute_average_angle << std::endl
74  << "Compute average shift: " << compute_average_shift << std::endl
75  ;
76 }
bool compute_average_angle
Compute angle mean.
bool compute_average_shift
Compute shift mean.
int ang
The set of angles to be used for output.

Member Data Documentation

◆ ang

int ProgAngularDistance::ang

The set of angles to be used for output.

Definition at line 63 of file angular_distance.h.

◆ check_mirrors

bool ProgAngularDistance::check_mirrors

Check mirrors for Spider APMQ

Definition at line 49 of file angular_distance.h.

◆ compute_average_angle

bool ProgAngularDistance::compute_average_angle

Compute angle mean.

Definition at line 65 of file angular_distance.h.

◆ compute_average_shift

bool ProgAngularDistance::compute_average_shift

Compute shift mean.

Definition at line 67 of file angular_distance.h.

◆ compute_weights

bool ProgAngularDistance::compute_weights

Compute weights

Definition at line 53 of file angular_distance.h.

◆ DF1

MetaDataVec ProgAngularDistance::DF1

Definition at line 70 of file angular_distance.h.

◆ DF2

MetaDataVec ProgAngularDistance::DF2

Definition at line 72 of file angular_distance.h.

◆ fn_ang1

FileName ProgAngularDistance::fn_ang1

Filename angle doc 1

Definition at line 41 of file angular_distance.h.

◆ fn_ang2

FileName ProgAngularDistance::fn_ang2

Filename angle doc 2

Definition at line 43 of file angular_distance.h.

◆ fn_out

FileName ProgAngularDistance::fn_out

Filename of output file with merging

Definition at line 47 of file angular_distance.h.

◆ fn_sym

FileName ProgAngularDistance::fn_sym

Filename symmetry file

Definition at line 45 of file angular_distance.h.

◆ idLabel

String ProgAngularDistance::idLabel

Definition at line 59 of file angular_distance.h.

◆ minSigma

double ProgAngularDistance::minSigma

Minimum angular sigma

Definition at line 55 of file angular_distance.h.

◆ minSigmaD

double ProgAngularDistance::minSigmaD

Minimum displacement sigma

Definition at line 57 of file angular_distance.h.

◆ object_rotation

bool ProgAngularDistance::object_rotation

Use object rotations

Definition at line 51 of file angular_distance.h.

◆ set

int ProgAngularDistance::set

Set of angular difference.

Definition at line 61 of file angular_distance.h.

◆ SL

SymList ProgAngularDistance::SL

Definition at line 74 of file angular_distance.h.


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