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
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
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 ");
85 addParamsLine(
" --ang1 <Metadata1> : Angular document file 1");
86 addParamsLine(
" --ang2 <Metadata2> : Angular document file 2");
87 addParamsLine(
" [--oroot <rootname=\"\">] : Output rootname");
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");
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,");
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 ");
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");
129 "Angular_distance: Input Docfiles with different number of entries");
145 double angular_distance=0;
146 double shift_distance=0;
149 X_diff, Y_diff, shift_diff;
151 tilt_diff.
resize(rot_diff);
152 psi_diff.
resize(rot_diff);
153 vec_diff.
resize(rot_diff);
156 shift_diff.
resize(rot_diff);
163 std::vector<double> output;
165 bool fillOutput=
fn_out!=
"";
167 auto iter1(
DF1.
ids().begin());
168 auto iter2(
DF2.
ids().begin());
171 for (i = 0; i < s; ++
i, ++iter1, ++iter2)
175 double rot1, tilt1, psi1;
176 double rot2, tilt2, psi2;
177 double rot2p, tilt2p, psi2p;
179 double X1, X2, Y1, Y2;
209 rot2p, tilt2p, psi2p,
false,
211 angular_distance += distp;
214 rot_diff(i) = rot1 - rot2p;
215 tilt_diff(i) = tilt1 - tilt2p;
216 psi_diff(i) = psi1 - psi2p;
220 shift_diff(i) =
sqrt(X_diff(i)*X_diff(i)+Y_diff(i)*Y_diff(i));
221 shift_distance += shift_diff(i);
232 double rotAvg, tiltAvg, psiAvg;
234 rot2p, tilt2p, psi2p,
235 rotAvg, tiltAvg, psiAvg );
314 angular_distance /=
i;
340 std::cout <<
"Global angular distance = " << angular_distance << std::endl;
341 std::cout <<
"Global shift distance = " << shift_distance << std::endl;
350 std::vector<MDLabel> labels;
351 labels.push_back(label);
360 MDLabel angleDiffLabel, shiftDiffLabel, weightLabel;
382 auto iter1(DF1sorted.
ids().begin());
383 auto iter2(DF2sorted.
ids().begin());
384 std::vector< Matrix1D<double> > ang1, ang2;
387 bool anotherImageIn2 = iter2 != DF2sorted.
ids().end();
390 while (anotherImageIn2)
396 DF2sorted.
getValue(label,currentId, *iter2);
399 bool anotherIteration=
false;
402 DF2sorted.
getValue(label,id2,*iter2);
403 anotherIteration=
false;
414 double rotp, tiltp, psip;
417 YY(rotTiltPsi)=tiltp;
420 ang2.push_back(rotTiltPsi);
422 if (iter2 != DF2sorted.
ids().end())
423 anotherIteration=
true;
425 }
while (anotherIteration);
428 double N=0, cumulatedDistance=0, cumulatedDistanceShift=0;
430 if (iter1 != DF1sorted.
ids().end() && *iter1 > 0)
432 DF1sorted.
getValue(label,id1,*iter1);
433 const auto lastID = DF1sorted.
ids().end();
434 while (id1<currentId && iter1 != lastID)
437 if (iter1 != DF1sorted.
ids().end())
438 DF1sorted.
getValue(label,id1,*iter1);
442 if (iter1 == DF1sorted.
ids().end())
446 anotherIteration=
false;
449 DF1sorted.
getValue(label,id1,*iter1);
450 anotherIteration=
false;
461 double rotp, tiltp, psip;
464 YY(rotTiltPsi)=tiltp;
467 ang1.push_back(rotTiltPsi);
469 if (iter1 != DF1sorted.
ids().end())
470 anotherIteration=
true;
472 }
while (anotherIteration);
477 for (
size_t i=0;
i<ang2.size(); ++
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)
487 double rot1=
XX(anglesj);
488 double tilt1=
YY(anglesj);
489 double psi1=
ZZ(anglesj);
492 if (dist<bestDistance)
498 bestShiftDistance*=0.5;
499 if (bestDistance<360)
501 cumulatedDistance+=bestDistance;
502 cumulatedDistanceShift+=bestShiftDistance;
507 DFweights.
setValue(label,currentId,newObjId);
514 double meanDistance=cumulatedDistance/ang2.size();
515 DFweights.
setValue(angleDiffLabel,meanDistance,newObjId);
516 double meanDistanceShift=cumulatedDistanceShift/ang2.size();
517 DFweights.
setValue(shiftDiffLabel,meanDistanceShift,newObjId);
524 DFweights.
setValue(angleDiffLabel,-1.0,newObjId);
525 DFweights.
setValue(shiftDiffLabel,-1.0,newObjId);
529 anotherImageIn2 = iter2 != DF2sorted.
ids().end();
534 DFweights.
setValue(label,currentId,newObjId);
535 DFweights.
setValue(angleDiffLabel,-1.0,newObjId);
536 DFweights.
setValue(shiftDiffLabel,-1.0,newObjId);
540 const auto totalSize = DF2sorted.
ids().end();
541 while (iter2 != totalSize)
544 DFweights.
setValue(label,currentId,newObjId);
545 DFweights.
setValue(angleDiffLabel,-1.0,newObjId);
546 DFweights.
setValue(shiftDiffLabel,-1.0,newObjId);
551 std::vector<double> angleDistances, shiftDistances;
555 double sigma2=0, sigma2D=0, N=0;
556 for (
size_t i=0;
i<angleDistances.size(); ++
i)
558 double d=angleDistances[
i];
569 std::cout <<
"Sigma of angular distances=" <<
sqrt(sigma2) << std::endl;
572 std::cout <<
"Sigma of shift distances=" <<
sqrt(sigma2D) << std::endl;
575 double isigma2=-0.5/sigma2;
576 double isigma2D=-0.5/sigma2D;
578 for (
size_t objId : DFweights.
ids())
582 DFweights.
getValue(angleDiffLabel,d,objId);
584 weight=exp(d*d*isigma2);
590 DFweights.
getValue(shiftDiffLabel,d,objId);
592 weight*=exp(d*d*isigma2D);
596 DFweights.
setValue(weightLabel,weight,objId);
609 for (
size_t objId : DF2weighted.
ids())
612 DF2weighted.
getValue(angleDiffLabel,d,objId);
616 DF2weighted.
setValue(angleDiffLabel,0.0,objId);
618 DF2weighted.
getValue(shiftDiffLabel,d,objId);
622 DF2weighted.
setValue(shiftDiffLabel,0.0,objId);
633 const double ai = -
DEG2RAD(rot) / 2;
634 const double aj =
DEG2RAD(tilt) / 2;
635 const double ak = -
DEG2RAD(psi) / 2;
638 const double si = std::sin(ai),
645 const double cc = ci * ck,
652 q[0] = +cj * (cc - ss);
653 q[1] = +sj * (cs - sc);
654 q[2] = -sj * (cc + ss);
655 q[3] = +cj * (cs + sc);
659 double& rot,
double& tilt,
double&
psi )
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];
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;
692 const auto sy =
std::sqrt(m21*m21 + m20*m20);
695 ax = std::atan2(m21, m20);
696 ay = std::atan2(sy, m22);
697 az = std::atan2(m12, -m02);
699 ax = std::atan2(-m10, m11);
700 ay = std::atan2(sy, m22);
710 double rot2,
double tilt2,
double psi2,
711 double& rot,
double& tilt,
double&
psi )
724 firstEigs(m, 1UL, eigvals, eigvecs,
true);
733 double shiftX2,
double shiftY2,
734 double& shiftX,
double& shiftY )
736 shiftX = (shiftX1 + shiftX2) / 2;
737 shiftY = (shiftY1 + shiftY2) / 2;
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)
double getDoubleParam(const char *param, int arg=0)
static MDLabel str2Label(const String &labelName)
#define REPORT_ERROR(nerr, ErrormMsg)
void sqrt(Image< double > &op)
void setValue(const MDObject &object) override
int readSymmetryFile(FileName fn_sym, double accuracy=SYM_ACCURACY)
static void euler2quat(double rot, double tilt, double psi, double q[4])
void Euler_mirrorY(double rot, double tilt, double psi, double &newrot, double &newtilt, double &newpsi)
void matrixOperation_AtA(const Matrix2D< double > &A, Matrix2D< double > &B)
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.
Incorrect number of objects in Metadata.
void readParams()
Read argument from command line.
#define MAT_ELEM(m, i, j)
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)
const char * getParam(const char *param, int arg=0)
void compute_hist(const MultidimArrayGeneric &array, Histogram1D &hist, int no_steps)
void firstEigs(const Matrix2D< double > &A, size_t M, Matrix1D< double > &D, Matrix2D< double > &P, bool Pneeded)
static void quat2Euler(const double q[4], double &rot, double &tilt, double &psi)
void max(Image< double > &op1, const Image< double > &op2)
Error related to numerical calculation.
int verbose
Verbosity level.
bool compute_average_shift
Compute shift mean.
void defineParams()
Define parameters.
double psi(const double x)
void write(const FileName &fn, MDLabel=MDL_X, MDLabel=MDL_COUNT)
#define realWRAP(x, x0, xF)
bool checkParam(const char *param)
void addUsageLine(const char *line, bool verbatim=false)
int ang
The set of angles to be used for output.
int getIntParam(const char *param, int arg=0)
Incorrect value received.
#define MATRIX2D_ARRAY(m)
void addParamsLine(const String &line)