Xmipp  v3.23.11-Nereus
tomo_align_refinement.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Carlos Oscar Sanchez Sorzano coss@cnb.csic.es (2006)
4  *
5  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  * 02111-1307 USA
21  *
22  * All comments concerning this program package may be sent to the
23  * e-mail address 'xmipp@cnb.csic.es'
24  ***************************************************************************/
25 
26 #include "tomo_align_refinement.h"
27 #include "core/metadata_vec.h"
28 #include "core/transformations.h"
29 #include "data/filters.h"
31 #include "data/projection.h"
32 
33 // Empty constructor =======================================================
35 {
36  rot=tilt=psi=x=y=corr=0;
37  fn_img="";
38 }
39 
40 // Read arguments ==========================================================
42 {
43  fn_ref = getParam("--ref");
44  fn_sel = getParam("--sel");
45  fn_out = getParam("--oroot");
46  max_rot_change = getDoubleParam("--max_rot_change");
47  max_tilt_change = getDoubleParam("--max_tilt_change");
48  max_psi_change = getDoubleParam("--max_psi_change");
49  rot_step = getDoubleParam("--rot_step");
50  tilt_step = getDoubleParam("--tilt_step");
51  psi_step = getDoubleParam("--psi_step");
52  max_shift_change = getDoubleParam("--max_shift_change");
53  shift_step = getDoubleParam("--shift_step");
54  adjustGray = checkParam("--adjustGray");
55  generateAligned = checkParam("--generateAligned");
56 }
57 
58 // Show ====================================================================
60 {
61  std::cout
62  << "Reference images: " << fn_ref << std::endl
63  << "Input images: " << fn_sel << std::endl
64  << "Ouput rootname: " << fn_out << std::endl
65  << "Max rot change: " << max_rot_change << " step: " << rot_step << std::endl
66  << "Max tilt change: " << max_tilt_change << " step: " << tilt_step << std::endl
67  << "Max psi change: " << max_psi_change << " step: " << psi_step << std::endl
68  << "Max shift change: " << max_shift_change << " step: " << shift_step << std::endl
69  << "Adjust gray: " << adjustGray << std::endl
70  << "Generate aligned: " << generateAligned << std::endl
71  ;
72 }
73 
74 // usage ===================================================================
76 {
77  addUsageLine("Realign a tilt series with respect to a volume following a single ");
78  addUsageLine("particles approach, i.e., the volume is reprojected and the alignment");
79  addUsageLine("parameters are reoptimized.");
80  addParamsLine(" --ref <volume> : Reference volume");
81  addParamsLine(" --sel <selfile> : Images to align");
82  addParamsLine(" --oroot <rootname> : rootname for the output");
83  addParamsLine(" : rootname.doc contains a selfile with the");
84  addParamsLine(" : images realigned");
85  addParamsLine(" : rootname.stk contains the aligned and");
86  addParamsLine(" : adjusted images in case --adjustGray or");
87  addParamsLine(" : --generateAligned are given");
88  addParamsLine(" [--max_rot_change <ang=2>] : Maximum change allowed in rot");
89  addParamsLine(" [--max_tilt_change <ang=2>] : Maximum change allowed in tilt");
90  addParamsLine(" [--max_psi_change <ang=2>] : Maximum change allowed in psi");
91  addParamsLine(" [--max_shift_change <r=10>] : Maximum change allowed in shift");
92  addParamsLine(" [--rot_step <ang=0.25>] : Rot search step");
93  addParamsLine(" [--tilt_step <ang=0.25>] : Tilt search step");
94  addParamsLine(" [--psi_step <ang=0.25>] : Psi search step");
95  addParamsLine(" [--shift_step <r=2>] : Step in shift in pixels");
96  addParamsLine(" [--adjustGray] : Adjust also gray values");
97  addParamsLine(" [--generateAligned] : Generate aligned images");
98 }
99 
100 // Produce side information ================================================
101 //#define DEBUG
103 {
104  V.read(fn_ref);
105  V().setXmippOrigin();
106  MetaDataVec SF(fn_sel);
107  Image<double> I;
108  FileName fnImg;
109  ApplyGeoParams params;
110  params.datamode = HEADER;
111 
112  for (size_t objId : SF.ids())
113  {
115  SF.getValue(MDL_IMAGE,fnImg,objId);
116  I.readApplyGeo(fnImg,SF,objId, params);
117  I().setXmippOrigin();
118  dummy.rot=I.rot();
119  dummy.tilt=I.tilt();
120  dummy.psi=I.psi();
121  dummy.x=I.Xoff();
122  dummy.y=I.Yoff();
123  dummy.fn_img=fnImg;
124  dummy.corr=-1;
125  list_of_assigned.push_back(dummy);
126  }
127 }
128 #undef DEBUG
129 
130 // Look for best angles -------------------------------------------------
131 //#define DEBUG
133  const FileName &fnImgOut)
134 {
135  AlignmentTomography newAlignment=list_of_assigned[idx];
136  Image<double> I, Ip;
137  MultidimArray<int> mask;
138  I.read(list_of_assigned[idx].fn_img);
139  I().setXmippOrigin();
140  mask.resizeNoCopy(I());
141 
142  double rot0=list_of_assigned[idx].rot-max_rot_change;
143  double rotF=list_of_assigned[idx].rot+max_rot_change;
144  double tilt0=list_of_assigned[idx].tilt-max_tilt_change;
145  double tiltF=list_of_assigned[idx].tilt+max_tilt_change;
146  if (idx>0)
147  tilt0=XMIPP_MAX(tilt0,
148  (list_of_assigned[idx].tilt+list_of_assigned[idx-1].tilt)/2);
149  if (idx<list_of_assigned.size()-1)
150  tiltF=XMIPP_MIN(tiltF,
151  (list_of_assigned[idx].tilt+list_of_assigned[idx+1].tilt)/2);
152 
153  Projection theo;
155 #ifdef DEBUG
156 
157  std::cout << "original idx,rot,tilt,psi,x,y=" << idx << " "
158  << newAlignment.rot << " " << newAlignment.tilt
159  << " " << newAlignment.psi << " "
160  << newAlignment.x << " " << newAlignment.y << std::endl;
161 #endif
162 
163  for (double rot = rot0; rot <= rotF; rot += rot_step)
164  for (double tilt = tilt0; tilt <= tiltF; tilt += tilt_step)
165  {
166  Ip()=I();
167  // Take a projection from the given direction
168  projectVolume(V(), theo, YSIZE(V()), XSIZE(V()), rot, tilt, 0);
169  mask.initConstant(1);
171  if (IMGPIXEL(theo,i,j)==0 || IMGPIXEL(Ip,i,j)==0)
172  {
173  A2D_ELEM(mask,i,j)=0;
174  IMGPIXEL(Ip,i,j)=0;
175  }
176  double newCorr=correlationIndex(theo(),Ip(),&mask);
177  if (newCorr>newAlignment.corr)
178  {
179  newAlignment.rot = rot;
180  newAlignment.tilt = tilt;
181  newAlignment.corr=newCorr;
182  if (adjustGray)
183  Ip().rangeAdjust(theo(),&mask);
184  if (adjustGray || generateAligned)
185  Ip.write(fnImgOut);
186 #ifdef DEBUG
187 
188  std::cout << " Improved " << idx << " rot=" << rot << " tilt=" << tilt
189  << " x,y="
190  << newAlignment.x << " " << newAlignment.y << " psi="
191  << newAlignment.psi << " corr="
192  << newCorr << std::endl;
193  Image<double> save;
194  save()=Ip();
195  save.write("PPPexp.xmp");
196  save()=theo();
197  save.write("PPPtheo.xmp");
198  typeCast(mask,save());
199  save.write("PPPmask.xmp");
200  save()=theo()-Ip();
201  save.write("PPPdiff.xmp");
202 #endif
203 
204  }
205 
206  // Look for better alignment
207  alignImages(theo(),Ip(),M, xmipp_transformation::DONT_WRAP);
208 
209  // Measure the new correlation
210  newCorr=correlationIndex(theo(),Ip(),&mask);
211 
212  // Keep the value
213  if (newCorr>newAlignment.corr)
214  {
215  newAlignment.rot = rot;
216  newAlignment.tilt = tilt;
217  bool flip;
218  double scale;
219  newAlignment.M=M;
220  transformationMatrix2Parameters2D(M, flip, scale, newAlignment.x, newAlignment.y,
221  newAlignment.psi);
222  if (adjustGray)
223  Ip().rangeAdjust(theo(),&mask);
224  if (adjustGray || generateAligned)
225  Ip.write(fnImgOut);
226 #ifdef DEBUG
227 
228  std::cout << " Improved " << idx << " rot=" << rot << " tilt=" << tilt
229  << " x,y="
230  << newAlignment.x << " " << newAlignment.y << " psi="
231  << newAlignment.psi << " corr="
232  << newCorr << std::endl;
233  newAlignment.corr = newCorr;
234  Image<double> save;
235  save() = Ip();
236  save.write("PPPexpRealigned.xmp");
237  save()=theo()-Ip();
238  save.write("PPPdiffRealigned.xmp");
239  std::cout << "Press any key\n";
240  char c;
241  std::cin >> c;
242 #endif
243 
244  }
245  }
246 
247  // Select best alignment
248  list_of_assigned[idx]=newAlignment;
249 }
250 #undef DEBUG
251 
252 // Finish processing ---------------------------------------------------------
254 {
255  produce_side_info();
256  MetaDataVec DF;
257  FileName fnMaskOut, fnImgOut;
258  Projection theo;
259  Image<double> Imask, I;
260  FileName fn_tmp(fn_out + ".stk");
261  if (adjustGray)
262  fn_tmp.deleteFile();
263 
264  for (size_t i=0; i<list_of_assigned.size(); i++)
265  {
266  if (adjustGray || generateAligned)
267  fnImgOut.compose(i+1,fn_out+".stk");
268  else
269  fnImgOut=list_of_assigned[i].fn_img;
270 
271  // Get angles and shifts
272  predict_angles(i,fnImgOut);
273 
274  // Store them in the output docfile
275  size_t id = DF.addObject();
276  DF.setValue(MDL_IMAGE,fnImgOut,id);
277  DF.setValue(MDL_IMAGE_ORIGINAL,list_of_assigned[i].fn_img,id);
278  DF.setValue(MDL_ANGLE_ROT,list_of_assigned[i].rot,id);
279  DF.setValue(MDL_ANGLE_TILT,list_of_assigned[i].tilt,id);
280  DF.setValue(MDL_ANGLE_PSI,list_of_assigned[i].psi,id);
281  DF.setValue(MDL_SHIFT_X,list_of_assigned[i].x,id);
282  DF.setValue(MDL_SHIFT_Y,list_of_assigned[i].y,id);
283  DF.setValue(MDL_MAXCC,list_of_assigned[i].corr,id);
284  }
285  DF.write(fn_out+".doc");
286 }
void predict_angles(size_t i, const FileName &fnImgOut)
void defineParams()
Define parameters.
Rotation angle of an image (double,degrees)
#define YSIZE(v)
#define A2D_ELEM(v, i, j)
#define XMIPP_MAX(x, y)
Definition: xmipp_macros.h:193
void transformationMatrix2Parameters2D(const Matrix2D< T > &A, bool &flip, T &scale, T &shiftX, T &shiftY, T &psi)
Matrix2D< double > M
double alignImages(const MultidimArray< double > &Iref, const AlignmentTransforms &IrefTransforms, MultidimArray< double > &I, Matrix2D< double > &M, bool wrap, AlignmentAux &aux, CorrelationAux &aux2, RotationalCorrelationAux &aux3)
Definition: filters.cpp:2047
double psi(const size_t n=0) const
doublereal * c
void resizeNoCopy(const MultidimArray< T1 > &v)
Tilting angle of an image (double,degrees)
Shift for the image in the X axis (double)
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)
double correlationIndex(const MultidimArray< T > &x, const MultidimArray< T > &y, const MultidimArray< int > *mask=NULL, MultidimArray< double > *Contributions=NULL)
void compose(const String &str, const size_t no, const String &ext="")
Special label to be used when gathering MDs in MpiMetadataPrograms.
void initConstant(T val)
void write(const FileName &outFile, WriteModeMetaData mode=MD_OVERWRITE) const
double rot(const size_t n=0) const
virtual IdIteratorProxy< false > ids()
int readApplyGeo(const FileName &name, const MDRow &row, const ApplyGeoParams &params=DefaultApplyGeoParams)
#define i
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
double tilt(const size_t n=0) const
Name of an image from which MDL_IMAGE is coming from.
bool setValue(const MDObject &mdValueIn, size_t id)
size_t addObject() override
#define XSIZE(v)
double Yoff(const size_t n=0) const
void readParams()
Read arguments from command line.
void projectVolume(FourierProjector &projector, Projection &P, int Ydim, int Xdim, double rot, double tilt, double psi, const MultidimArray< double > *ctf)
Maximum cross-correlation for the image (double)
double dummy
#define XMIPP_MIN(x, y)
Definition: xmipp_macros.h:181
#define j
void deleteFile() const
bool getValue(MDObject &mdValueOut, size_t id) const override
void typeCast(const Matrix1D< T1 > &v1, Matrix1D< T2 > &v2)
Definition: matrix1d.h:1227
double Xoff(const size_t n=0) const
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false, int mode=WRITE_READONLY)
Shift for the image in the Y axis (double)
Name of an image (std::string)
#define IMGPIXEL(I, i, j)