Xmipp  v3.23.11-Nereus
frm.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Carlos Oscar S. Sorzano (coss@cnb.csic.es)
4  *
5  *
6  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21  * 02111-1307 USA
22  *
23  * All comments concerning this program package may be sent to the
24  * e-mail address 'xmipp@cnb.csic.es'
25  ***************************************************************************/
26 
27 #include "frm.h"
28 #include <core/geometry.h>
29 #include <core/transformations.h>
30 
31 //#define DEBUG
32 #ifdef DEBUG
33 #include <core/xmipp_image.h>
34 #endif
35 void alignVolumesFRM(PyObject *pFunc, const MultidimArray<double> &Iref, MultidimArray<double> &I,
36  PyObject *Imask,
37  double &rot, double &tilt, double &psi, double &x, double &y, double &z, double &score,
39  int maxshift, double maxFreq, const MultidimArray<int> *mask)
40 {
41  PyObject *pyIref = Python::convertToNumpy(Iref);
42  PyObject *pyI = Python::convertToNumpy(I);
43  PyObject *pyMask=Py_None;
44  if (mask!=nullptr)
45  pyMask=Python::convertToNumpy(*mask);
46 
47 //#define DEBUG
48 #ifdef DEBUG
49  Image<double> save;
50  save()=I;
51  save.write("PPPI.vol");
52  save()=Iref;
53  save.write("PPPIref.vol");
54  std::cout << "Imask=" << Imask << std::endl;
55  std::cout << "Press any key\n";
56  char c; std::cin >> c;
57 #endif
58 
59  // Call frm
60  int bandWidthSphericalHarmonics0=4;
61  int bandWidthSphericalHarmonicsF=64;
62  auto frequencyPixels=(int)(XSIZE(Iref)*maxFreq);
63  PyObject *arglistfrm = Py_BuildValue("OOOO(ii)iiO", pyI, Imask, pyIref, Py_None,
64  bandWidthSphericalHarmonics0, bandWidthSphericalHarmonicsF, frequencyPixels, maxshift, pyMask);
65  PyObject *resultfrm = PyObject_CallObject(pFunc, arglistfrm);
66  Py_DECREF(arglistfrm);
67  Py_DECREF(pyIref);
68  Py_DECREF(pyI);
69  if (mask!=nullptr)
70  Py_DECREF(pyMask);
71  if (resultfrm!=nullptr)
72  {
73  PyObject *shift=PyTuple_GetItem(resultfrm,0);
74  PyObject *euler=PyTuple_GetItem(resultfrm,1);
75  score=PyFloat_AsDouble(PyTuple_GetItem(resultfrm,2));
76  double xfrm=PyFloat_AsDouble(PyList_GetItem(shift,0))-XSIZE(Iref)/2;
77  double yfrm=PyFloat_AsDouble(PyList_GetItem(shift,1))-YSIZE(Iref)/2;
78  double zfrm=PyFloat_AsDouble(PyList_GetItem(shift,2))-ZSIZE(Iref)/2;
79  double angz1=PyFloat_AsDouble(PyList_GetItem(euler,0));
80  double angz2=PyFloat_AsDouble(PyList_GetItem(euler,1));
81  double angx=PyFloat_AsDouble(PyList_GetItem(euler,2));
82  Matrix2D<double> Efrm, E(3,3);
83  Euler_anglesZXZ2matrix(-angz1, -angx, -angz2, Efrm); // -angles because FRM rotation definition
84  // is the opposite of Xmipp
85 
86  // Reorganize the matrix because the Z and X axes in the coordinate system are reversed with
87  // respect to Xmipp
88  // Exmipp=[0 0 1; 0 1 0; 1 0 0]*Efrm*[0 0 1; 0 1 0; 1 0 0]
89  MAT_ELEM(E,0,0)=MAT_ELEM(Efrm, 2, 2); MAT_ELEM(E,0,1)=MAT_ELEM(Efrm, 2, 1); MAT_ELEM(E,0,2)=MAT_ELEM(Efrm, 2, 0);
90  MAT_ELEM(E,1,0)=MAT_ELEM(Efrm, 1, 2); MAT_ELEM(E,1,1)=MAT_ELEM(Efrm, 1, 1); MAT_ELEM(E,1,2)=MAT_ELEM(Efrm, 1, 0);
91  MAT_ELEM(E,2,0)=MAT_ELEM(Efrm, 0, 2); MAT_ELEM(E,2,1)=MAT_ELEM(Efrm, 0, 1); MAT_ELEM(E,2,2)=MAT_ELEM(Efrm, 0, 0);
92  E=E.inv();
93  Euler_matrix2angles(E,rot,tilt,psi);
94  Py_DECREF(resultfrm);
95 
96  x=-zfrm;
97  y=-yfrm;
98  z=-xfrm;
99 
100  // Apply
101  Euler_angles2matrix(rot, tilt, psi, A, true);
102  Matrix2D<double> Aaux;
103  Matrix1D<double> r(3);
104  XX(r)=x;
105  YY(r)=y;
106  ZZ(r)=z;
107  translation3DMatrix(r,Aaux);
108  A=A*Aaux;
109 #ifdef DEBUG
110  std::cout << "Result: " << rot << " " << tilt << " " << psi << " " << x << " " << y << " " << z << " -> " << score << std::endl;
111 #endif
112  }
113  else
114  {
115  x=y=z=rot=tilt=psi=score=0;
116  A.initIdentity(4);
117 
118  std::cout << "No result\n";
119  std::cout << Python::print_traceback();
120  }
121 }
122 #undef DEBUG
#define YSIZE(v)
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
doublereal * c
static double * y
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)
void inv(Matrix2D< T > &result) const
Definition: matrix2d.cpp:663
doublereal * x
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
#define XX(v)
Definition: matrix1d.h:85
template void translation3DMatrix(const Matrix1D< float > &translation, Matrix2D< float > &resMatrix, bool inverse)
#define XSIZE(v)
#define ZSIZE(v)
double z
#define YY(v)
Definition: matrix1d.h:93
PyObject * convertToNumpy(const MultidimArray< T > &array)
void alignVolumesFRM(PyObject *pFunc, const MultidimArray< double > &Iref, MultidimArray< double > &I, PyObject *Imask, double &rot, double &tilt, double &psi, double &x, double &y, double &z, double &score, Matrix2D< double > &A, int maxshift, double maxFreq, const MultidimArray< int > *mask)
Definition: frm.cpp:35
void Euler_anglesZXZ2matrix(double a, double b, double g, Matrix2D< double > &A, bool homogeneous)
Definition: geometry.cpp:661
double psi(const double x)
void Euler_matrix2angles(const Matrix2D< double > &A, double &alpha, double &beta, double &gamma, bool homogeneous)
Definition: geometry.cpp:839
std::string print_traceback()
#define ZZ(v)
Definition: matrix1d.h:101
void initIdentity()
Definition: matrix2d.h:673