Xmipp  v3.23.11-Nereus
volume_align_prog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Carlos Oscar S. Sorzano (coss@cnb.csic.es)
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 "interface/frm.h" // must be included first as it defines _POSIX_C_SOURCE
27 #include <fstream>
28 #include "core/xmipp_image.h"
29 #include "data/filters.h"
30 #include "core/geometry.h"
31 #include "data/mask.h"
32 #include "core/xmipp_program.h"
33 #include "core/transformations.h"
34 
35 // Alignment parameters needed by fitness ----------------------------------
37 {
38 public:
39 #define COVARIANCE 1
40 #define LEAST_SQUARES 2
41 
43 
48 
49  bool wrap;
50 };
51 
52 // Global parameters needed by fitness ------------------------------------
53 static AlignParams params; // create one version for each cpp file
54 
55 // Apply transformation ---------------------------------------------------
58  double *p,
59  bool wrap)
60 {
61  Matrix1D<double> r(3);
62  Matrix2D<double> A, Aaux;
63 
64  double greyScale = p[0];
65  double greyShift = p[1];
66  double rot = p[2];
67  double tilt = p[3];
68  double psi = p[4];
69  double scale = p[5];
70  ZZ(r) = p[6];
71  YY(r) = p[7];
72  XX(r) = p[8];
73 
74  Euler_angles2matrix(rot, tilt, psi, A, true);
75  translation3DMatrix(r,Aaux);
76  A = A * Aaux;
77  scale3DMatrix(vectorR3(scale, scale, scale),Aaux);
78  A = A * Aaux;
79 
80  applyGeometry(xmipp_transformation::LINEAR, Vaux, V2, A, xmipp_transformation::IS_NOT_INV, wrap);
81  if (greyScale!=1 || greyShift!=0)
83  DIRECT_MULTIDIM_ELEM(Vaux,n)=DIRECT_MULTIDIM_ELEM(Vaux,n)*greyScale+greyShift;
84 }
85 
86 
87 // Fitness between two volumes --------------------------------------------
88 double fitness(double *p)
89 {
90  applyTransformation(params.V2(),params.Vaux(),p, params.wrap);
91 
92  // Correlate
93  double fit=0.;
94  switch (params.alignment_method)
95  {
96  case COVARIANCE:
97  fit = -correlationIndex(params.V1(), params.Vaux(), params.mask_ptr);
98  break;
99  case LEAST_SQUARES:
100  fit = rms(params.V1(), params.Vaux(), params.mask_ptr);
101  break;
102  }
103  return fit;
104 }
105 
106 
107 double wrapperFitness(double *p, void *params)
108 {
109  return fitness(p+1);
110 }
111 
112 
114 {
115 public:
117 
118  FileName fn1, fn2;
119  double rot0, rotF, tilt0, tiltF, psi0, psiF;
120  double step_rot, step_tilt, step_psi;
121  double scale0, scaleF, step_scale;
122  double z0, zF, y0, yF, x0, xF, step_z, step_y, step_x;
123  double grey_scale0, grey_scaleF, step_grey;
124  double grey_shift0, grey_shiftF, step_grey_shift;
125  int tell;
126  bool apply;
127  FileName fnOut, fnGeo, fnGray, fnStore;
129  bool usePowell, onlyShift, useFRM, copyGeo, copyGray, store, wrap;
130  double maxFreq;
131  int maxShift;
132  bool dontScale;
133  int starting_tilt, ending_tilt; //compensating for a single tilt wedge mask (tomography data)
134 public:
135 
137  {
138 
139  addUsageLine("Align two volumes varying orientation, position and scale");
140  addParamsLine(" --i1 <volume1> : the first volume to align");
141  addParamsLine(" --i2 <volume2> : the second one");
142  addParamsLine(" [--rot <rot0=0> <rotF=0> <step_rot=1>] : in degrees");
143  addParamsLine(" [--tilt <tilt0=0> <tiltF=0> <step_tilt=1>] : in degrees");
144  addParamsLine(" [--psi <psi0=0> <psiF=0> <step_psi=1>] : in degrees");
145  addParamsLine(" [--scale <sc0=1> <scF=1> <step_sc=1>] : size scale margin");
146  addParamsLine(" [--grey_scale <sc0=1> <scF=1> <step_sc=1>] : grey scale margin");
147  addParamsLine(" requires --least_squares;");
148  addParamsLine(" [--grey_shift <sh0=0> <shF=0> <step_sh=1>] : grey shift margin");
149  addParamsLine(" requires --least_squares;");
150  addParamsLine(" [-z <z0=0> <zF=0> <step_z=1>] : Z position in pixels");
151  addParamsLine(" [-y <y0=0> <yF=0> <step_y=1>] : Y position in pixels");
152  addParamsLine(" [-x <x0=0> <xF=0> <step_x=1>] : X position in pixels");
153  addParamsLine(" [--show_fit] : Show fitness values");
154  addParamsLine(" [--apply <file=\"\">] : Apply best movement to --i2 and store results in this file");
155  addParamsLine(" [--covariance] : Covariance fitness criterion");
156  addParamsLine(" [--least_squares] : LS fitness criterion");
157  addParamsLine(" [--local] : Use local optimizer instead of exhaustive search");
158  addParamsLine(" [--frm <maxFreq=0.25> <maxShift=10> <tilt0=-90> <tiltF=90>] : Use Fast Rotational Matching, if tilt0 and tiltF are left as -90 and 90 they do not effect the results of the alignment");
159  addParamsLine(" : Maximum frequency is in digital frequencies (<0.5)");
160  addParamsLine(" : Maximum shift is in pixels");
161  addParamsLine(" :+ See Y. Chen, et al. Fast and accurate reference-free alignment of subtomograms. JSB, 182: 235-245 (2013)");
162  addParamsLine(" [--onlyShift] : Only shift");
163  addParamsLine(" [--dontScale] : Do not look for scale changes");
164  addParamsLine(" [--copyGeo <file=\"\">] : copy transformation matrix in a txt file. ('A' matrix elements)");
165  addParamsLine(" [--copyGray <file=\"\">] : copy gray scale and shift txt file.)");
166  addParamsLine(" [--store <file=\"\">] : copy angles and shifts to a txt file.");
167  addParamsLine(" [--dontWrap] : Do not wrap input2 when aligning to input1");
168  addParamsLine(" == Mask Options == ");
169  mask.defineParams(this,INT_MASK,nullptr,nullptr,true);
170  addExampleLine("Typically you first look for a rough approximation of the alignment using exhaustive search. For instance, for a global rotational alignment use",false);
171  addExampleLine("xmipp_volume_align --i1 volume1.vol --i2 volume2.vol --rot 0 360 15 --tilt 0 180 15 --psi 0 360 15");
172  addExampleLine("Then, assume the best alignment is obtained for rot=45, tilt=60, psi=90",false);
173  addExampleLine("Now you perform a local search to refine the estimation and apply",false);
174  addExampleLine("xmipp_volume_align --i1 volume1.vol --i2 volume2.vol --rot 45 --tilt 60 --psi 90 --local --apply volume2aligned.vol");
175  addSeeAlsoLine("xmipp_volumeset_align");
176  }
177 
178  void readParams()
179  {
180  // Get parameters =======================================================
181  fn1 = getParam("--i1");
182  fn2 = getParam("--i2");
183 
184  rot0 = getDoubleParam("--rot",0);
185  rotF = getDoubleParam("--rot",1);
186  step_rot = getDoubleParam("--rot",2);
187 
188  tilt0 = getDoubleParam("--tilt",0);
189  tiltF = getDoubleParam("--tilt",1);
190  step_tilt = getDoubleParam("--tilt",2);
191 
192  psi0 = getDoubleParam("--psi",0);
193  psiF = getDoubleParam("--psi",1);
194  step_psi = getDoubleParam("--psi",2);
195 
196  scale0 = getDoubleParam("--scale",0);
197  scaleF = getDoubleParam("--scale",1);
198  step_scale = getDoubleParam("--scale",2);
199 
200  grey_scale0 = getDoubleParam("--grey_scale",0);
201  grey_scaleF = getDoubleParam("--grey_scale",1);
202  step_grey = getDoubleParam("--grey_scale",2);
203 
204  grey_shift0 = getDoubleParam("--grey_shift",0);
205  grey_shiftF = getDoubleParam("--grey_shift",1);
206  step_grey_shift = getDoubleParam("--grey_shift",2);
207 
208  z0 = getDoubleParam("-z",0);
209  zF = getDoubleParam("-z",1);
210  step_z = getDoubleParam("-z",2);
211 
212  y0 = getDoubleParam("-y",0);
213  yF = getDoubleParam("-y",1);
214  step_y = getDoubleParam("-y",2);
215 
216  x0 = getDoubleParam("-x",0);
217  xF = getDoubleParam("-x",1);
218  step_x = getDoubleParam("-x",2);
219 
220  mask_enabled = checkParam("--mask");
221  if (mask_enabled)
222  mask.read(argc, argv);
223 
224  usePowell = checkParam("--local");
225  useFRM = checkParam("--frm");
226  if (useFRM)
227  {
228  maxFreq=getDoubleParam("--frm",0);
229  maxShift=getIntParam("--frm",1);
230  starting_tilt=getIntParam("--frm",2);
231  ending_tilt=getIntParam("--frm",3);
232  }
233  onlyShift = checkParam("--onlyShift");
234  wrap = !checkParam("--dontWrap");
235 
236  if (step_rot == 0)
237  step_rot = 1;
238  if (step_tilt == 0)
239  step_tilt = 1;
240  if (step_psi == 0)
241  step_psi = 1;
242  if (step_scale == 0)
243  step_scale = 1;
244  if (step_grey == 0)
245  step_grey = 1;
246  if (step_grey_shift == 0)
247  step_grey_shift = 1;
248  if (step_z == 0)
249  step_z = 1;
250  if (step_y == 0)
251  step_y = 1;
252  if (step_x == 0)
253  step_x = 1;
254 
255  tell = checkParam("--show_fit");
256  apply = checkParam("--apply");
257  fnOut = getParam("--apply");
258  copyGeo = checkParam("--copyGeo");
259  copyGray = checkParam("--copyGray");
260  fnGeo = getParam("--copyGeo");
261  fnGray = getParam("--copyGray");
262  store = checkParam("--store");
263  fnStore = getParam("--store");
264  dontScale = checkParam("--dontScale");
265 
266  if (checkParam("--covariance"))
267  {
268  params.alignment_method = COVARIANCE;
269  }
270  else if (checkParam("--least_squares"))
271  {
273  }
274  else
275  {
276  params.alignment_method = COVARIANCE;
277  }
278  }
279 
280  void run ()
281  {
283 
284  // Main program =========================================================
285  params.V1.read(fn1);
286  params.V1().setXmippOrigin();
287  params.V2.read(fn2);
288  params.V2().setXmippOrigin();
289  params.wrap = wrap;
290 
291  // Initialize best_fit
292  double best_fit = 1e38;
293  Matrix1D<double> best_align(8);
294  bool first = true;
295 
296  // Generate mask
297  if (mask_enabled)
298  {
299  mask.generate_mask(params.V1());
300  params.mask_ptr = &(mask.get_binary_mask());
301  }
302  else
303  params.mask_ptr = nullptr;
304 
305  // Exhaustive search
306  if (!usePowell && !useFRM)
307  {
308  // Count number of iterations
309  int times = 1;
310  if (!tell)
311  {
312  if (grey_scale0 != grey_scaleF)
313  times *= FLOOR(1 + (grey_scaleF - grey_scale0) / step_grey);
314  if (grey_shift0 != grey_shiftF)
315  times *= FLOOR(1 + (grey_shiftF - grey_shift0) / step_grey_shift);
316  if (rot0 != rotF)
317  times *= FLOOR(1 + (rotF - rot0) / step_rot);
318  if (tilt0 != tiltF)
319  times *= FLOOR(1 + (tiltF - tilt0) / step_tilt);
320  if (psi0 != psiF)
321  times *= FLOOR(1 + (psiF - psi0) / step_psi);
322  if (scale0 != scaleF)
323  times *= FLOOR(1 + (scaleF - scale0) / step_scale);
324  if (z0 != zF)
325  times *= FLOOR(1 + (zF - z0) / step_z);
326  if (y0 != yF)
327  times *= FLOOR(1 + (yF - y0) / step_y);
328  if (x0 != xF)
329  times *= FLOOR(1 + (xF - x0) / step_x);
330  init_progress_bar(times);
331  }
332  else
333  std::cout << "#grey_factor rot tilt psi scale z y x fitness\n";
334 
335  // Iterate
336  int itime = 0;
337  int step_time = CEIL((double)times / 60.0);
338  Matrix1D<double> r(3);
339  Matrix1D<double> trial(9);
340  for (double grey_scale = grey_scale0; grey_scale <= grey_scaleF ; grey_scale += step_grey)
341  for (double grey_shift = grey_shift0; grey_shift <= grey_shiftF ; grey_shift += step_grey_shift)
342  for (double rot = rot0; rot <= rotF ; rot += step_rot)
343  for (double tilt = tilt0; tilt <= tiltF ; tilt += step_tilt)
344  for (double psi = psi0; psi <= psiF ; psi += step_psi)
345  for (double scale = scale0; scale <= scaleF ; scale += step_scale)
346  for (ZZ(r) = z0; ZZ(r) <= zF ; ZZ(r) += step_z)
347  for (YY(r) = y0; YY(r) <= yF ; YY(r) += step_y)
348  for (XX(r) = x0; XX(r) <= xF ; XX(r) += step_x)
349  {
350  // Form trial vector
351  trial(0) = grey_scale;
352  trial(1) = grey_shift;
353  trial(2) = rot;
354  trial(3) = tilt;
355  trial(4) = psi;
356  trial(5) = scale;
357  trial(6) = ZZ(r);
358  trial(7) = YY(r);
359  trial(8) = XX(r);
360  // Evaluate
361  double fit = fitness(MATRIX1D_ARRAY(trial));
362  // The best?
363  if (fit < best_fit || first)
364  {
365  best_fit = fit;
366  best_align = trial;
367  first = false;
368  if (tell)
369  std::cout << "Best so far\n";
370  }
371  // Show fit
372  if (tell)
373  std::cout << trial << " " << fit << std::endl;
374  else
375  if (++itime % step_time == 0)
376  progress_bar(itime);
377  }
378  if (!tell)
379  progress_bar(times);
380  }
381  else if (usePowell)
382  {
383  // Use Powell optimization
384  Matrix1D<double> x(9), steps(9);
385  double fitness;
386  int iter;
387  steps.initConstant(1);
388  if (onlyShift)
389  steps(0)=steps(1)=steps(2)=steps(3)=steps(4)=steps(5)=0;
390  if (params.alignment_method == COVARIANCE)
391  steps(0)=steps(1)=0;
392  if (dontScale)
393  steps(5)=0;
394  x(0)=grey_scale0;
395  x(1)=grey_shift0;
396  x(2)=rot0;
397  x(3)=tilt0;
398  x(4)=psi0;
399  x(5)=scale0;
400  x(6)=z0;
401  x(7)=y0;
402  x(8)=x0;
403 
404  powellOptimizer(x,1,9,&wrapperFitness,nullptr,0.01,fitness,iter,steps,true);
405  best_align=x;
406  best_fit=fitness;
407  first=false;
408  }
409  else if (useFRM)
410  {
412  PyObject * pFunc = Python::getFunctionRef("sh_alignment.frm", "frm_align");
413  double rot,tilt,psi,x,y,z,score;
415  if(starting_tilt!=-90 || ending_tilt!=90){
416  std::cout<<"you are compensating for the missing wedge, the first volume should be rotated with 90 degrees about the y-axis"<<std::endl;
417  PyObject * pSTMMclass = Python::getClassRef("sh_alignment.tompy.filter", "SingleTiltWedge");
418  PyObject * arglist = Py_BuildValue("(ii)", starting_tilt , ending_tilt);
419  PyObject * SingleTiltWedgeMask = PyObject_CallObject(pSTMMclass, arglist);
420  // The order of volumes has to be flipped in order to compensate for a single tilt missing wedge. For those who are not using this mask, no changes in results will happen.
421  alignVolumesFRM(pFunc, params.V2(), params.V1(), SingleTiltWedgeMask, rot,tilt,psi,x,y,z,score,A,maxShift,maxFreq,params.mask_ptr);
422  std::cout<<"If you intend to apply transform using xmipp_transform_geometry, use --inverse flag (if it was not present before), or remove it (if it was present before)"<<std::endl;
423  Py_DECREF(SingleTiltWedgeMask);
424  Py_DECREF(arglist);
425  Py_DECREF(pSTMMclass);
426  }
427  else{
428  alignVolumesFRM(pFunc, params.V1(), params.V2(), Py_None, rot,tilt,psi,x,y,z,score,A,maxShift,maxFreq,params.mask_ptr);
429  }
430  best_align.initZeros(9);
431  best_align(0)=1; // Gray scale
432  best_align(1)=0; // Gray shift
433  best_align(2)=rot;
434  best_align(3)=tilt;
435  best_align(4)=psi;
436  best_align(5)=1; // Scale
437  best_align(6)=z;
438  best_align(7)=y;
439  best_align(8)=x;
440  best_fit=-score;
441  first=false;
442  }
443 
444  if (!first)
445  std::cout << "The best correlation is for\n"
446  << "Scale : " << best_align(5) << std::endl
447  << "Translation (X,Y,Z) : " << best_align(8)
448  << " " << best_align(7) << " " << best_align(6)
449  << std::endl
450  << "Rotation (rot,tilt,psi): "
451  << best_align(2) << " " << best_align(3) << " "
452  << best_align(4) << std::endl
453  << "Best grey scale : " << best_align(0) << std::endl
454  << "Best grey shift : " << best_align(1) << std::endl
455  << "Fitness value : " << best_fit << std::endl;
456  Matrix1D<double> r(3);
457  XX(r) = best_align(8);
458  YY(r) = best_align(7);
459  ZZ(r) = best_align(6);
460  Matrix2D<double> A,Aaux;
461 
462  Euler_angles2matrix(best_align(2), best_align(3), best_align(4),
463  A, true);
464 
465  translation3DMatrix(r,Aaux);
466 
467  //A = A + Aaux;
468  //A(0,0) -= 1;
469  //A(1,1) -= 1;
470  //A(2,2) -= 1;
471  //A(3,3) -= 1;
472  A = A * Aaux;
473 
474  scale3DMatrix(vectorR3(best_align(5), best_align(5), best_align(5)),Aaux);
475  A = A * Aaux;
476 
477  if (verbose!=0)
478  std::cout << "xmipp_transform_geometry will require the following values"
479  << "\n Angles: " << best_align(2) << " "
480  << best_align(3) << " " << best_align(4)
481  << "\n Shifts: " << A(0,3) << " " << A(1,3) << " " << A(2,3)
482  << std::endl;
483  if (copyGeo)
484  {
485  std::ofstream outputGeo (fnGeo.c_str());
486  outputGeo << A(0,0) << "\n" << A(0,1) << "\n" << A(0,2) << "\n" << A(0,3) << "\n"
487  << A(1,0) << "\n" << A(1,1) << "\n" << A(1,2) << "\n" << A(1,3) << "\n"
488  << A(2,0) << "\n" << A(2,1) << "\n" << A(2,2) << "\n" << A(2,3) << "\n"
489  << A(3,0) << "\n" << A(3,1) << "\n" << A(3,2) << "\n" << A(3,3) << "\n"
490  << std::endl;
491  outputGeo.close();
492  }
493  if (copyGray)
494  {
495  std::ofstream outputGray (fnGray.c_str());
496  outputGray << best_align(0) << "\n"
497  << best_align(1) << "\n"
498  << std::endl;
499  outputGray.close();
500  }
501  if (store)
502  {
503  std::ofstream outputStore (fnStore.c_str());
504  outputStore << best_align(2) << ", " << best_align(3) << ", " << best_align(4) << ", " << A(0,3) << ", "
505  << A(1,3) << ", " << A(2,3) << ", " << best_fit << std::endl;
506  outputStore.close();
507  }
508  if (apply)
509  {
510  applyTransformation(params.V2(),params.Vaux(),MATRIX1D_ARRAY(best_align), wrap);
511  params.V2()=params.Vaux();
512  params.V2.write(fnOut);
513  }
514  }
515 };
void init_progress_bar(long total)
double rms(const MultidimArray< T > &x, const MultidimArray< T > &y, const MultidimArray< int > *mask=nullptr, MultidimArray< double > *Contributions=nullptr)
Definition: filters.h:725
double wrapperFitness(double *p, void *params)
#define COVARIANCE
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
Definition: mask.h:360
static double * y
Image< double > Vaux
Image< double > V2
Matrix1D< double > vectorR3(double x, double y, double z)
Definition: matrix1d.cpp:892
void applyGeometry(int SplineDegree, MultidimArray< std::complex< double > > &V2, const MultidimArray< std::complex< double > > &V1, const Matrix2D< double > &A, bool inv, bool wrap, std::complex< double > outside, MultidimArray< double > *BcoeffsPtr)
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)
int allowed_data_types
Definition: mask.h:495
#define zF
void powellOptimizer(Matrix1D< double > &p, int i0, int n, double(*f)(double *x, void *), void *prm, double ftol, double &fret, int &iter, const Matrix1D< double > &steps, bool show)
#define z0
glob_prnt iter
void applyTransformation(const MultidimArray< double > &V2, MultidimArray< double > &Vaux, double *p, bool wrap)
void initPythonAndNumpy()
doublereal * x
Image< double > V1
static void defineParams(XmippProgram *program, int allowed_data_types=ALL_KINDS, const char *prefix=nullptr, const char *comment=nullptr, bool moreOptions=false)
Definition: mask.cpp:1203
void read(int argc, const char **argv)
Definition: mask.cpp:701
glob_log first
#define LEAST_SQUARES
#define FLOOR(x)
Definition: xmipp_macros.h:240
#define y0
#define x0
#define XX(v)
Definition: matrix1d.h:85
template void translation3DMatrix(const Matrix1D< float > &translation, Matrix2D< float > &resMatrix, bool inverse)
#define CEIL(x)
Definition: xmipp_macros.h:225
FileName fnOut
PyObject * getFunctionRef(const std::string &moduleName, const std::string &funcName)
void progress_bar(long rlen)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
double z
#define DIRECT_MULTIDIM_ELEM(v, n)
const MultidimArray< int > * mask_ptr
void scale3DMatrix(const Matrix1D< double > &sc, Matrix2D< double > &result, bool homogeneous)
#define xF
void initZeros()
Definition: matrix1d.h:592
PyObject * getClassRef(const std::string &moduleName, const std::string &className)
double steps
#define YY(v)
Definition: matrix1d.h:93
void generate_mask(bool apply_geo=false)
Definition: mask.cpp:1577
#define MATRIX1D_ARRAY(v)
Definition: matrix1d.h:58
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
double psi(const double x)
#define INT_MASK
Definition: mask.h:385
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false, int mode=WRITE_READONLY)
const MultidimArray< int > & get_binary_mask() const
Definition: mask.h:707
void initConstant(T val)
Definition: matrix1d.cpp:83
#define yF
int * n
double fitness(double *p)
#define ZZ(v)
Definition: matrix1d.h:101