34 addUsageLine(
"Takes two coordinates sets and defines the coordinate transformation between them");
35 addUsageLine(
"First set defines the untilted coordinates, second set defines the tilted coordinates");
36 addParamsLine(
" --tilt <metadata> : Metadata with angular assignment for the tilted images");
37 addParamsLine(
" --untilt <metadata> : Metadata with angular assignment for the untilted images");
38 addParamsLine(
" -o <metadata> : Metadata with matrix transformation");
54 double cr, ct, cp, sr, st, sp;
55 std::complex<double> I(0,1);
64 L[0] = cr*ct*cp - sr*ct*sp;
65 L[1] = I*(sr*st*cp - cr*st*sp);
66 L[2] = I*(cr*st*cp + sr*st*sp);
67 L[3] = I*(sr*ct*cp+cr*ct*sp);
72 std::complex<double> (&P)[4])
76 std::complex<double> I(0,1);
77 std::complex<double> aux=0.5;
80 P[2]=I*(M[1]-M[2])*aux;
85 std::complex<double> (&Inver)[4])
91 std::complex<double> Inver_matrix[4], mat[4];
92 std::complex<double> NOriginal;
96 Inver_matrix[0] = mat[3];
97 Inver_matrix[1] = -mat[1];
98 Inver_matrix[2] = -mat[2];
99 Inver_matrix[3] = mat[0];
105 std::complex<double> (&Inver)[4])
111 std::complex<double> Inver_matrix[4];
113 Inver_matrix[0] = Original[3];
114 Inver_matrix[1] = -Original[1];
115 Inver_matrix[2] = -Original[2];
116 Inver_matrix[3] = Original[0];
123 std::complex<double> I(0,1);
125 M[1] = (P[1]-I*P[2]);
126 M[2] = (P[1]+I*P[2]);
131 std::complex<double> (&P)[4])
133 std::complex<double> A_matrix[4], B_matrix[4], aux[4];
138 aux[0] = A_matrix[0]*B_matrix[0] + A_matrix[1]*B_matrix[2];
139 aux[2] = A_matrix[2]*B_matrix[0] + A_matrix[3]*B_matrix[2];
140 aux[1] = A_matrix[0]*B_matrix[1] + A_matrix[1]*B_matrix[3];
141 aux[3] = A_matrix[2]*B_matrix[1] + A_matrix[3]*B_matrix[3];
148 std::complex<double> I(0,1);
149 std::complex<double> aux1 = I*R[1]/R[0], aux2 = I*R[2]/R[0], alpha_aux_x, alpha_aux_y;
151 if ((aux1.imag() == 0) && (aux2.imag() == 0))
153 alpha_aux_x = 2*atan(aux1.real());
154 alpha_aux_y = 2*atan(aux2.real());
155 alpha_x = alpha_aux_x.real()*180/
PI;
156 alpha_y = alpha_aux_y.real()*180/
PI;
160 std::cout <<
"Error, argument of atan is complex" << std::endl;
166 double tilt_angles[3],
double alpha_x,
double alpha_y)
168 double rotu = untilt_angles[0], tiltu = untilt_angles[1], psiu = untilt_angles[2];
169 double rott = tilt_angles[0], tiltt = tilt_angles[1], psit = tilt_angles[2];
170 std::complex<double> qu[4], M[4], Inv_qu[4], qt[4], R[4];
179 std::cout <<
"alpha_x = " << alpha_x << std::endl;
180 std::cout <<
"alpha_y = " << alpha_y << std::endl;
185 MetaDataVec MD_tilted, MD_untilted, DF1sorted, DF2sorted, DFweights;
193 auto iter1(DF1sorted.
ids().begin()), iter2(DF2sorted.
ids().begin());
194 std::vector< Matrix1D<double> > ang1, ang2;
197 bool anotherImageIn2 = iter2 != DF2sorted.
ids().end();
202 while (anotherImageIn2)
211 bool anotherIteration=
false;
215 anotherIteration=
false;
222 std::cout <<
"From DF2:" <<
XX(rotTiltPsi) <<
" " <<
YY(rotTiltPsi) <<
" " <<
ZZ(rotTiltPsi) <<
" " << mirror << std::endl;
226 double rotp, tiltp, psip;
229 YY(rotTiltPsi)=tiltp;
232 ang2.push_back(rotTiltPsi);
234 if (iter2 != DF2sorted.
ids().end())
235 anotherIteration=
true;
237 }
while (anotherIteration);
240 double N=0, cumulatedDistance=0;
245 while (id1<currentId && iter1 != DF1sorted.
ids().end())
252 if (iter1 == DF1sorted.
ids().end())
259 anotherIteration=
false;
266 std::cout <<
"From DF1:" <<
XX(rotTiltPsi) <<
" " <<
YY(rotTiltPsi) <<
" " <<
ZZ(rotTiltPsi) <<
" " << mirror << std::endl;
270 double rotp, tiltp, psip;
273 YY(rotTiltPsi)=tiltp;
276 ang1.push_back(rotTiltPsi);
278 if (iter1 != DF1sorted.
ids().end())
279 anotherIteration=
true;
281 }
while (anotherIteration);
284 for (
size_t i=0;
i<ang2.size(); ++
i)
287 double rotu=
XX(anglesi);
288 double tiltu=
YY(anglesi);
289 double psiu=
ZZ(anglesi);
297 for (
size_t j=0;
j<ang1.size(); ++
j)
300 double rott=
XX(anglesj);
301 double tiltt=
YY(anglesj);
302 double psit=
ZZ(anglesj);
307 double untilt_angles[3]={rotu, tiltu, psiu}, tilt_angles[3]={rott, tiltt, psit};
318 double rotTransf, tiltTransf, psiTransf;
320 std::cout <<
"Rot_and_Tilt " << rotTransf <<
" " << tiltTransf << std::endl;
323 XX(z) = Eu(2,0) - Et(2,0);
324 YY(z) = Eu(2,1) - Et(2,1);
325 ZZ(z) = Eu(2,2) - Et(2,2);
327 alpha = atan2(
YY(z),
XX(z));
328 beta = atan2(
XX(z)/cos(alpha),
ZZ(z));
329 std::cout <<
"alpha = " << alpha*180/
PI << std::endl;
330 std::cout <<
"beta = " << beta*180/
PI << std::endl;
339 double meanDistance=cumulatedDistance/ang2.size();
345 anotherImageIn2 = iter2 != DF2sorted.
ids().end();
348 std::complex<double> qu[4], qt[4], M[4], Inv_qu[4], P1[4], Inv_quu[4];
349 double rotu=34*
PI/180, tiltu=10*
PI/180, psiu=5*
PI/180;
350 double rott=25*
PI/180, tiltt=15*
PI/180, psit=40*
PI/180;
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
double beta(const double a, const double b)
void inverse_matrixSU2(std::complex< double > Original[4], std::complex< double >(&Inver)[4])
Inverse of a matrix (expressed in Pauli basis)
void extrarotationangles(std::complex< double > R[4], double &alpha_x, double &alpha_y)
Extract angles alpha_x and alpha_y from the transformation matrix.
void Paulibasis2matrix(std::complex< double > P[4], std::complex< double >(&M)[4])
A Pauli span is converted to a 2x2 matrix.
void InversefromPaulibasis(std::complex< double > Original[4], std::complex< double >(&Inver)[4])
Matrix2D< T > transpose() const
void quaternion2Paulibasis(double rot, double tilt, double psi, std::complex< double >(&L)[4])
Transform a set of angles/orientations to a matrix expressed in Pauli basis.
const char * getParam(const char *param, int arg=0)
void Euler_mirrorX(double rot, double tilt, double psi, double &newrot, double &newtilt, double &newpsi)
void readParams()
Read parameters from the command line.
void defineParams()
Define parameters in the command line.
void Pauliproduct(std::complex< double > A[4], std::complex< double > B[4], std::complex< double >(&P)[4])
It calculates the product of two matrix expressed in Pauli matrices by their matrix elements A an B...
FileName fnuntiltimage_In
void angles2tranformation(double untilt_angles[3], double tilt_angles[3], double alpha_x, double alpha_y)
It takes two sets of angles (rotu, tiltu, psiu) which define Eu, and (rott, tiltt, psit) which define Et,.
double psi(const double x)
void Euler_matrix2angles(const Matrix2D< double > &A, double &alpha, double &beta, double &gamma, bool homogeneous)
void matrix2Paulibasis(std::complex< double > M[4], std::complex< double >(&P)[4])
It takes a 2x2 matrix (where M[0] = m11; M[1]=m12; M[2]=m21; M[3]=m22) and express the matrix M...
void addUsageLine(const char *line, bool verbatim=false)
void addParamsLine(const String &line)
void run()
Execute de program.