Xmipp  v3.23.11-Nereus
recons_misc.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 <fstream>
27 #include "recons_misc.h"
28 #include "basic_art.h"
29 #include "core/metadata_vec.h"
30 #include "core/symmetries.h"
31 #include "data/mask.h"
32 #include "data/projection.h"
33 #include "data/wavelet.h"
34 #include "symmetrize.h"
35 
36 /* Fill Reconstruction info structure -------------------------------------- */
38  const FileName &fn_ctf, const SymList &SL,
39  ReconsInfo * &IMG_Inf, bool do_not_use_symproj)
40 {
41  Matrix2D<double> L(4, 4), R(4, 4); // A matrix from the list
42  FileName fn_proj;
43  FileName fn_ctf1;
44  Projection read_proj;
45  bool is_there_ctf = false;
46  bool is_ctf_unique = false;
47 
48  int trueIMG = selfile.size();
49  selfile.firstRowId();
50  int numIMG;
51  if (!do_not_use_symproj)
52  numIMG = trueIMG * (SL.symsNo() + 1);
53  else
54  numIMG = trueIMG;
55 
56  // The next two ifs check whether there is a CTF file, and
57  // whether it is unique
58  if (fn_ctf != "")
59  {
60  is_there_ctf = true;
61  is_ctf_unique = true;
62  }
63  else if (selfile.containsLabel(MDL_CTF_MODEL))
64  {
65  is_there_ctf = true;
66  is_ctf_unique = false;
67  }
68 
69  if (IMG_Inf != nullptr)
70  delete [] IMG_Inf;
71  if ((IMG_Inf = new ReconsInfo[numIMG]) == nullptr)
72  REPORT_ERROR(ERR_MEM_NOTENOUGH, "Build_Recons_Info: No memory for the sorting");
73 
74  int i = 0; // It will account for the number of valid projections processed
75  std::cout << "Reading angle information ...\n";
76  init_progress_bar(trueIMG);
77  for (size_t objId : selfile.ids())
78  {
79  ReconsInfo &imgInfo = IMG_Inf[i];
80  selfile.getValue(MDL_IMAGE,fn_proj,objId);
81  if (is_there_ctf && !is_ctf_unique)
82  selfile.getValue(MDL_CTF_MODEL,fn_ctf1,objId);
83  if (fn_proj != "")
84  {
85  // read_proj.read(fn_proj, false, HEADER);
86  // Filling structure
87  imgInfo.fn_proj = fn_proj;
88  imgInfo.row = selfile.getRowVec(objId);
89  imgInfo.row.detach();
90  if (is_ctf_unique)
91  imgInfo.fn_ctf = fn_ctf;
92  else if (is_there_ctf)
93  imgInfo.fn_ctf = fn_ctf1;
94  imgInfo.sym = -1;
95  imgInfo.seed = ROUND(65535 * rnd_unif());
96 
97  imgInfo.rot = imgInfo.tilt = imgInfo.psi = 0;
98 
99  selfile.getValue(MDL_ANGLE_ROT, imgInfo.rot,objId);
100  selfile.getValue(MDL_ANGLE_TILT, imgInfo.tilt,objId);
101  selfile.getValue(MDL_ANGLE_PSI, imgInfo.psi,objId);
102  // read_proj.getEulerAngles(imgInfo.rot, imgInfo.tilt, imgInfo.psi);
103  EULER_CLIPPING(imgInfo.rot, imgInfo.tilt, imgInfo.psi);
104 
105  // Any symmetry?
106  if (SL.symsNo() > 0 && !do_not_use_symproj)
107  {
108  for (int j = 0; j < SL.symsNo(); j++)
109  {
110  int sym_index = SYMINDEX(SL, j, i, trueIMG);
111  IMG_Inf[sym_index].fn_proj = imgInfo.fn_proj;
112  IMG_Inf[sym_index].seed = imgInfo.seed;
113  if (is_ctf_unique)
114  IMG_Inf[sym_index].fn_ctf = fn_ctf;
115  else if (is_there_ctf)
116  IMG_Inf[sym_index].fn_ctf = imgInfo.fn_ctf;
117  IMG_Inf[sym_index].sym = j;
118  SL.getMatrices(j, L, R);
119  L.resize(3, 3); // Erase last row and column
120  R.resize(3, 3); // as only the relative orientation
121  // is useful and not the translation
122  double drot, dtilt, dpsi;
123  Euler_apply_transf(L, R,
124  imgInfo.rot, imgInfo.tilt, imgInfo.psi,
125  drot, dtilt, dpsi);
126  IMG_Inf[sym_index].rot = (float)drot;
127  IMG_Inf[sym_index].tilt = (float)dtilt;
128  IMG_Inf[sym_index].psi = (float)dpsi;
129  }
130  }
131  }
132 
133  ++i; // I have processed one more image
134  if (i % 25 == 0)
135  progress_bar(i);
136  }
137  progress_bar(trueIMG);
138 }
139 
140 
141 
142 /* ------------------------------------------------------------------------- */
143 /* Sort_perpendicular */
144 /* ------------------------------------------------------------------------- */
145 void sortPerpendicular(int numIMG, ReconsInfo *IMG_Inf,
146  MultidimArray<int> &ordered_list, int N)
147 {
148  int i, j;
149  MultidimArray<short> chosen(numIMG); // 1 if that image has been already
150  // chosen
151  double min_prod;
152  int min_prod_proj=0;
153  Matrix2D<double> v(numIMG, 3);
154  Matrix2D<double> euler;
155  MultidimArray<double> product(numIMG);
156 
157  // Initialization
158  ordered_list.resize(numIMG);
159  for (i = 0; i < numIMG; i++)
160  {
162  // Initially no image is chosen
163  A1D_ELEM(chosen, i) = 0;
164 
165  // Compute the Euler matrix for each image and keep only
166  // the third row of each one
167  Euler_angles2matrix(IMG_Inf[i].rot, IMG_Inf[i].tilt, 0., euler);
168  euler.getRow(2, z);
169  v.setRow(i, z);
170  }
171 
172  // Pick first projection as the first one to be presented
173  i = 0;
174  A1D_ELEM(chosen, i) = 1;
175  A1D_ELEM(ordered_list, 0) = i;
176 
177  // Choose the rest of projections
178  std::cout << "Sorting projections ...\n";
179  init_progress_bar(numIMG - 1);
180  Matrix1D<double> rowj, rowi_1, rowi_N_1;
181  for (i = 1; i < numIMG; i++)
182  {
183  // Compute the product of not already chosen vectors with the just
184  // chosen one, and select that which has minimum product
185  min_prod = MAXFLOAT;
186  v.getRow(A1D_ELEM(ordered_list, i - 1),rowi_1);
187  if (N != -1 && i > N)
188  v.getRow(A1D_ELEM(ordered_list, i - N - 1),rowi_N_1);
189  for (j = 0; j < numIMG; j++)
190  {
191  if (!A1D_ELEM(chosen, j))
192  {
193  v.getRow(j,rowj);
194  A1D_ELEM(product, j) += ABS(dotProduct(rowi_1,rowj));
195  if (N != -1 && i > N)
196  A1D_ELEM(product, j) -= ABS(dotProduct(rowi_N_1,rowj));
197  if (A1D_ELEM(product, j) < min_prod)
198  {
199  min_prod = A1D_ELEM(product, j);
200  min_prod_proj = j;
201  }
202  }
203  }
204 
205  // Store the chosen vector and mark it as chosen
206  A1D_ELEM(ordered_list, i) = min_prod_proj;
207  A1D_ELEM(chosen, min_prod_proj) = 1;
208 
209  // The progress bar is updated only every 10 images
210  if (i % 10 == 0)
211  progress_bar(i);
212  }
213 
214  // A final call to progress bar to finish a possible small piece
215  progress_bar(numIMG - 1);
216  std::cout << std::endl;
217 }
218 
219 /* ------------------------------------------------------------------------- */
220 /* No Sort */
221 /* ------------------------------------------------------------------------- */
222 void noSort(int numIMG, MultidimArray<int> &ordered_list)
223 {
224  ordered_list.initLinear(0, numIMG - 1);
225 }
226 
227 /* ------------------------------------------------------------------------- */
228 /* Random Sort */
229 /* ------------------------------------------------------------------------- */
230 void sortRandomly(int numIMG, MultidimArray<int> &ordered_list)
231 {
232  MultidimArray<int> chosen;
233 
234  // Initialisation
235  ordered_list.resize(numIMG);
236  chosen.initZeros(numIMG);
237 
238  std::cout << "Randomizing projections ...\n";
239  init_progress_bar(numIMG - 1);
240  int ptr = 0;
242  for (int i = numIMG; i > 0; i--)
243  {
244  // Jump a random number starting at the pointed projection
245  int rnd_indx = (int) rnd_unif(0, i) + 1;
246  while (rnd_indx > 0)
247  {
248  // Jump one not chosen image
249  ptr = (ptr + 1) % numIMG;
250  // Check it is not chosen, if it is, go on skipping
251  while (chosen(ptr))
252  {
253  ptr = (ptr + 1) % numIMG;
254  }
255  rnd_indx--;
256  }
257 
258  // Annotate this image
259  A1D_ELEM(ordered_list, i - 1) = ptr;
260  A1D_ELEM(chosen, ptr) = 1;
261 
262  // The progress bar is updated only every 10 images
263  if (i % 10 == 0)
264  progress_bar(i);
265  }
266 
267  // A final call to progress bar to finish a possible small piece
268  progress_bar(numIMG - 1);
269  std::cout << std::endl;
270 }
271 
272 /* ------------------------------------------------------------------------- */
273 /* Update residual vector for WLS */
274 /* ------------------------------------------------------------------------- */
276  double &kappa, double &pow_residual_vol, double &pow_residual_imgs)
277 {
278  GridVolume residual_vol;
279  Projection read_proj, dummy_proj, new_proj;
280  FileName fn_resi, fn_tmp;
281  double sqrtweight, dim2;
282  Matrix2D<double> *A = nullptr;
283  std::vector<MultidimArray<double> > newres_imgs;
284  MultidimArray<int> mask;
285 
286  residual_vol.resize(vol_basis);
287  residual_vol.initZeros();
288 
289  // Calculate volume from all backprojected residual images
290  std::cout << "Backprojection of residual images " << std::endl;
291  if (!(prm.tell&TELL_SHOW_ERROR))
293 
294  for (int iact_proj = 0; iact_proj < prm.numIMG ; iact_proj++)
295  {
296  // backprojection of the weighted residual image
297  sqrtweight = sqrt(prm.residual_imgs[iact_proj].weight() / prm.sum_weight);
298  read_proj = prm.residual_imgs[iact_proj];
299  read_proj() *= sqrtweight;
300  dummy_proj().resize(read_proj());
301 
302  dummy_proj.setAngles(prm.IMG_Inf[iact_proj].rot,
303  prm.IMG_Inf[iact_proj].tilt,
304  prm.IMG_Inf[iact_proj].psi);
305 
306  project_GridVolume(residual_vol, prm.basis, dummy_proj,
307  read_proj, YSIZE(read_proj()), XSIZE(read_proj()),
308  prm.IMG_Inf[iact_proj].rot,
309  prm.IMG_Inf[iact_proj].tilt,
310  prm.IMG_Inf[iact_proj].psi, BACKWARD, prm.eq_mode,
311  prm.GVNeq, nullptr, nullptr, prm.ray_length, prm.threads);
312 
313  if (!(prm.tell&TELL_SHOW_ERROR))
314  if (iact_proj % XMIPP_MAX(1, prm.numIMG / 60) == 0)
315  progress_bar(iact_proj);
316  }
317  if (!(prm.tell&TELL_SHOW_ERROR))
318  progress_bar(prm.numIMG);
319 
320  // Convert to voxels: solely for output of power of residual volume
321  Image<double> residual_vox;
322  int Xoutput_volume_size = (prm.Xoutput_volume_size == 0) ?
323  prm.projXdim : prm.Xoutput_volume_size;
324  int Youtput_volume_size = (prm.Youtput_volume_size == 0) ?
325  prm.projYdim : prm.Youtput_volume_size;
326  int Zoutput_volume_size = (prm.Zoutput_volume_size == 0) ?
327  prm.projXdim : prm.Zoutput_volume_size;
328  prm.basis.changeToVoxels(residual_vol, &(residual_vox()),
329  Zoutput_volume_size, Youtput_volume_size, Xoutput_volume_size);
330  pow_residual_vol = residual_vox().sum2() / MULTIDIM_SIZE(residual_vox());
331  residual_vox.clear();
332 
333  std::cout << "Projection of residual volume; kappa = " << kappa << std::endl;
334  if (!(prm.tell&TELL_SHOW_ERROR))
336 
337  // Now that we have the residual volume: project in all directions
338  pow_residual_imgs = 0.;
339  new_proj().resize(read_proj());
340  mask.resize(read_proj());
341  BinaryCircularMask(mask, YSIZE(read_proj()) / 2, INNER_MASK);
342 
343  dim2 = (double)YSIZE(read_proj()) * XSIZE(read_proj());
344  for (int iact_proj = 0; iact_proj < prm.numIMG ; iact_proj++)
345  {
346  project_GridVolume(residual_vol, prm.basis, new_proj,
347  dummy_proj, YSIZE(read_proj()), XSIZE(read_proj()),
348  prm.IMG_Inf[iact_proj].rot,
349  prm.IMG_Inf[iact_proj].tilt,
350  prm.IMG_Inf[iact_proj].psi, FORWARD, prm.eq_mode,
351  prm.GVNeq, A, nullptr, prm.ray_length, prm.threads);
352 
353  sqrtweight = sqrt(prm.residual_imgs[iact_proj].weight() / prm.sum_weight);
354 
355  // Next lines like normalization in [EHL] (2.18)?
357  {
358  dAij(dummy_proj(), i, j) = XMIPP_MAX(1., dAij(dummy_proj(), i, j)); // to avoid division by zero
359  dAij(new_proj(), i, j) /= dAij(dummy_proj(), i, j);
360  }
361  new_proj() *= sqrtweight * kappa;
362 
363  /*
364  fn_tmp="residual_"+integerToString(iact_proj);
365  dummy_proj()=1000*prm.residual_imgs[iact_proj]();
366  dummy_proj.write(fn_tmp+".old");
367  */
368 
369  prm.residual_imgs[iact_proj]() -= new_proj();
370  pow_residual_imgs += prm.residual_imgs[iact_proj]().sum2();
371 
372  // Mask out edges of the images
373  apply_binary_mask(mask, prm.residual_imgs[iact_proj](), prm.residual_imgs[iact_proj](), 0.);
374 
375  /*
376  dummy_proj()=1000*new_proj();
377  dummy_proj.write(fn_tmp+".change");
378  dummy_proj()=1000*prm.residual_imgs[iact_proj]();
379  dummy_proj.write(fn_tmp+".new");
380  */
381 
382  if (!(prm.tell&TELL_SHOW_ERROR))
383  if (iact_proj % XMIPP_MAX(1, prm.numIMG / 60) == 0)
384  progress_bar(iact_proj);
385  }
386 
387  pow_residual_imgs /= dim2;
388  newres_imgs.clear();
389 
390  if (!(prm.tell&TELL_SHOW_ERROR))
391  progress_bar(prm.numIMG);
392 
393 }
394 
395 /* ------------------------------------------------------------------------- */
397  int _Zoutput_volume_size, int _Youtput_volume_size,
398  int _Xoutput_volume_size)
399 {
400  prm = _prm;
401  Zoutput_volume_size = _Zoutput_volume_size;
402  Youtput_volume_size = _Youtput_volume_size;
403  Xoutput_volume_size = _Xoutput_volume_size;
404  N = 0;
406 }
407 
409 {}
410 
411 //#define MODE7
412 #define MODE8
413 //#define MODE15
414 //#define DEBUG
416  Projection &read_proj)
417 {
418  Image<double> vol_voxels;
419 
420  // Convert from basis to voxels
421  prm->basis.changeToVoxels(*ptr_vol_out, &(vol_voxels()),
423  (*ptr_vol_out).initZeros();
424  N++;
425 
426  // Make the DWT
428 #ifdef MODE7
429 
430  int DWT_iterations = 2;
431  int keep_from_iteration = 0;
432 #endif
433 #ifdef MODE8
434 
435  int DWT_iterations = 2;
436  int keep_from_iteration = 0;
437 #endif
438 #ifdef MODE15
439 
440  int DWT_iterations = 2;
441  int keep_from_iteration = 0;
442 #endif
443 
444  Bilib_DWT(vol_voxels(), DWTV, DWT_iterations);
445 #ifdef DEBUG
446 
447  vol_voxels.write("PPPVariability.vol");
448  char c;
449  std::cout << "Press any key\n";
450  std::cin >> c;
451 #endif
452 
453  // Select the LLL block and keep it
454  int x1, x2, y1, y2, z1, z2;
455  SelectDWTBlock(keep_from_iteration, DWTV, "000", x1, x2, y1, y2, z1, z2);
456  DWTV.selfWindow(z1, y1, x1, z2, y2, x2);
457  STARTINGZ(DWTV) = STARTINGY(DWTV) = STARTINGX(DWTV) = 0;
458  VA.push_back(DWTV);
459 }
460 #undef DEBUG
461 
462 //#define DEBUG
464 {
465  if (VA.size() == 0)
466  return;
467 
468  // Coocurrence matrix
469  int nmax = VA.size();
470  MultidimArray<int> coocurrence(nmax, nmax);
471 
472  // Study each voxel
473  Image<double> SignificantT2, SignificantMaxRatio, SignificantMinRatio;
474  int zsize = ZSIZE(VA[0]) / 2;
475  int ysize = YSIZE(VA[0]) / 2;
476  int xsize = XSIZE(VA[0]) / 2;
477  SignificantT2().initZeros(zsize, ysize, xsize);
478  SignificantMaxRatio().initZeros(zsize, ysize, xsize);
479  SignificantMinRatio().initZeros(zsize, ysize, xsize);
480  std::cout << "Classifying voxels ...\n";
481  init_progress_bar(MULTIDIM_SIZE(SignificantT2()));
482  int counter = 0, nxny = ysize * zsize;
483 #ifdef MODE7
484 #define NFEATURES 7
485 #endif
486 #ifdef MODE8
487 #define NFEATURES 8
488 #endif
489 #ifdef MODE15
490 #define NFEATURES 15
491 #endif
492 
493  FOR_ALL_ELEMENTS_IN_ARRAY3D(SignificantT2())
494  {
495  // Save the data for this voxel
496  std::ofstream fh_dat;
497  fh_dat.open("PPP.dat");
498  if (!fh_dat)
499  REPORT_ERROR(ERR_IO_NOTOPEN, "VariabilityClass::finishAnalysis: "
500  "Cannot open PPP.dat for output");
501  fh_dat << NFEATURES << " " << nmax << std::endl;
502  std::vector< Matrix1D<double> > v;
503  v.clear();
504  for (int n = 0; n < nmax; n++)
505  {
507 
508 #ifdef MODE7
509 
510  v_aux(0) = VA[n](k, i, j + xsize);
511  v_aux(1) = VA[n](k, i + ysize, j);
512  v_aux(2) = VA[n](k, i + ysize, j + xsize);
513  v_aux(3) = VA[n](k + zsize, i, j);
514  v_aux(4) = VA[n](k + zsize, i, j + xsize);
515  v_aux(5) = VA[n](k + zsize, i + ysize, j);
516  v_aux(6) = VA[n](k + zsize, i + ysize, j + xsize);
517 #endif
518 #ifdef MODE8
519 
520  v_aux(0) = VA[n](k, i, j);
521  v_aux(1) = VA[n](k, i, j + xsize);
522  v_aux(2) = VA[n](k, i + ysize, j);
523  v_aux(3) = VA[n](k, i + ysize, j + xsize);
524  v_aux(4) = VA[n](k + zsize, i, j);
525  v_aux(5) = VA[n](k + zsize, i, j + xsize);
526  v_aux(6) = VA[n](k + zsize, i + ysize, j);
527  v_aux(7) = VA[n](k + zsize, i + ysize, j + xsize);
528 #endif
529 #ifdef MODE15
530 
531  v_aux(0) = VA[n](k / 2, i / 2, j / 2);
532  v_aux(1) = VA[n](k / 2, i / 2, j / 2 + xsize2);
533  v_aux(2) = VA[n](k / 2, i / 2 + ysize2, j / 2);
534  v_aux(3) = VA[n](k / 2, i / 2 + ysize2, j / 2 + xsize2);
535  v_aux(4) = VA[n](k / 2 + zsize2, i / 2, j / 2);
536  v_aux(5) = VA[n](k / 2 + zsize2, i / 2, j / 2 + xsize2);
537  v_aux(6) = VA[n](k / 2 + zsize2, i / 2 + ysize2, j / 2);
538  v_aux(7) = VA[n](k / 2 + zsize2, i / 2 + ysize2, j / 2 + xsize2);
539  v_aux(8) = VA[n](k, i, j + xsize);
540  v_aux(9) = VA[n](k, i + ysize, j);
541  v_aux(10) = VA[n](k, i + ysize, j + xsize);
542  v_aux(11) = VA[n](k + zsize, i, j);
543  v_aux(12) = VA[n](k + zsize, i, j + xsize);
544  v_aux(13) = VA[n](k + zsize, i + ysize, j);
545  v_aux(14) = VA[n](k + zsize, i + ysize, j + xsize);
546 #endif
547 
548  v_aux = v_aux * v_aux;
549  // COSS: Doesn't work: v_aux=v_aux.sort();
550 
551  fh_dat << v_aux.transpose() << std::endl;
552  v.push_back(v_aux);
553  }
554  fh_dat.close();
555 
556  // Classify
557  if (system("xmipp_fcmeans -din PPP.dat -std::cout PPP -c 2 -saveclusters > /dev/null")==-1)
558  REPORT_ERROR(ERR_UNCLASSIFIED,"Cannot open shell");
559 
560  // Pick up results
561  Matrix2D<double> aux;
562  int n_previous;
563 #define GET_RESULTS(fh,fn,avg,cov,N,idx) \
564  fh.open(fn);\
565  if (!fh) \
566  REPORT_ERROR(ERR_IO_NOTOPEN,(std::string)"VariabilityClass::finishAnalysis: " \
567  "Cannot open "+fn+" for input"); \
568  n_previous=-1; \
569  while (!fh.eof()) { \
570  int n; fh >> n; \
571  if (n!=n_previous) { \
572  n_previous=n; N++; \
573  idx(n)=1; \
574  avg+=v[n]; \
575  aux.fromVector(v[n]); \
576  cov+=aux*aux.transpose(); \
577  }\
578  } \
579  avg/=N; \
580  cov/=N; \
581  aux.fromVector(avg); \
582  cov-=aux*aux.transpose();
583 
584  std::ifstream fh_0;
586  Matrix1D<int> idx0(nmax);
587  Matrix2D<double> covariance0(NFEATURES, NFEATURES);
588  int N0 = 0;
589  GET_RESULTS(fh_0, "PPP.0", avg0, covariance0, N0, idx0);
590 #ifdef DEBUG
591 
592  std::cout << "Class 0 is:\n";
593  for (size_t n = 0; n < idx0.size(); n++)
594  {
595  if (idx0(n))
596  {
597  int iact_proj = prm->ordered_list(n);
598  std::cout << prm->IMG_Inf[iact_proj].fn_proj << std::endl;
599  }
600  }
601 #endif
602 
603  std::ifstream fh_1;
605  Matrix1D<int> idx1(nmax);
606  Matrix2D<double> covariance1(NFEATURES, NFEATURES);
607  int N1 = 0;
608  GET_RESULTS(fh_1, "PPP.1", avg1, covariance1, N1, idx1);
609 #ifdef DEBUG
610 
611  std::cout << "Class 1 is:\n";
612  for (size_t n = 0; n < idx1.size(); n++)
613  {
614  if (idx1(n))
615  {
616  int iact_proj = prm->ordered_list(n);
617  std::cout << prm->IMG_Inf[iact_proj].fn_proj << std::endl;
618  }
619  }
620 #endif
621 
622  Matrix2D<double> T2, covariance;
623  if (NFEATURES > 1)
624  {
625  // Perform T2-Hotelling test
626  Matrix1D<double> avg_diff = avg1 - avg0;
627  covariance = 1.0 / (N0 + N1 - 2) *
628  ((N0 - 1.0) * covariance0 + (N1 - 1.0) * covariance1);
629  covariance *= (1.0 / N0 + 1.0 / N1);
630  aux.fromVector(avg_diff);
631  T2 = (double)(N0 + N1 - avg_diff.size() - 1) /
632  ((N0 + N1 - 2) * avg_diff.size()) *
633  aux.transpose() * covariance.inv() * aux;
634  }
635  else
636  {
637  // Perform t-test
638  double variance = ((N0 - 1) * covariance0(0, 0) + (N1 - 1) * covariance1(0, 0)) /
639  (N0 + N1 - 2);
640  double t = (avg1(0) - avg0(0)) / sqrt(variance * (1.0 / N0 + 1.0 / N1));
641  T2.initZeros(1, 1);
642  T2(0, 0) = t;
643  }
644 
645  // Analysis of the covariance structure
646  Matrix1D<double> eigenvalues;
647  if (NFEATURES > 1)
648  {
649  Matrix2D<double> U, V;
650  svdcmp(covariance, U, eigenvalues, V);
651  }
652 
653  // Analysis of the coocurrences
654  for (size_t n = 0; n < idx0.size(); n++)
655  for (size_t np = n + 1; np < idx0.size(); np++)
656  if (idx0(n) && idx0(np))
657  coocurrence(n, np)++;
658 
659  for (size_t n = 0; n < idx1.size(); n++)
660  for (size_t np = n + 1; np < idx1.size(); np++)
661  if (idx1(n) && idx1(np))
662  coocurrence(n, np)++;
663 
664  // Keep results
665  SignificantT2(k, i, j) = T2(0, 0);
666  if (NFEATURES > 1)
667  {
668  SignificantMinRatio(k, i, j) = eigenvalues(1) / eigenvalues(0);
669  SignificantMaxRatio(k, i, j) = eigenvalues(NFEATURES - 1) / eigenvalues(0);
670  }
671 #ifdef DEBUG
672  std::cout << "T2 for this classification is " << T2(0, 0) << std::endl;
673  std::cout << "Eigenvalues are " << eigenvalues.transpose() << std::endl;
674 #endif
675 
676  if (++counter % nxny == 0)
677  progress_bar(counter);
678  }
679  progress_bar(MULTIDIM_SIZE(SignificantT2()));
680  SignificantT2.write(prm->fn_root + "_variability.vol");
681  SignificantMinRatio.write(prm->fn_root + "_minratio.vol");
682  SignificantMaxRatio.write(prm->fn_root + "_maxratio.vol");
683  if (system("rm PPP.dat PPP.cod PPP.vs PPP.err PPP.his PPP.inf PPP.0 PPP.1")==-1)
684  REPORT_ERROR(ERR_UNCLASSIFIED,"Cannot open shell");
685 
686  for (int n = 0; n < nmax; n++)
687  for (int np = n + 1; np < nmax; np++)
688  coocurrence(np, n) = coocurrence(n, np);
689  Image<double> save;
690  typeCast(coocurrence, save());
691  save.write(prm->fn_root + "_coocurrence.xmp");
692 }
693 #undef DEBUG
694 
695 /* ------------------------------------------------------------------------- */
696 #define POCS_N_measure 8
697 #define POCS_N_use 2
698 /* Constructor ............................................................. */
700  int _Zoutput_volume_size, int _Youtput_volume_size,
701  int _Xoutput_volume_size)
702 {
703  prm = _prm;
704  POCS_state = POCS_measuring;
705  POCS_freq = prm->POCS_freq;
706  POCS_i = 0;
707  POCS_vec_i = 0;
708  POCS_used = 0;
709  POCS_N = 0;
710  POCS_errors.initZeros(POCS_N_measure);
711  Zoutput_volume_size = _Zoutput_volume_size;
712  Youtput_volume_size = _Youtput_volume_size;
713  Xoutput_volume_size = _Xoutput_volume_size;
714  apply_POCS = (prm->surface_mask != nullptr ||
715  prm->positivity || (prm->force_sym != 0 && !prm->is_crystal) ||
716  prm->known_volume != -1);
717 }
718 
720 {
721  POCS_global_mean_error = 0;
722 }
723 
725 {
726  POCS_N = 0;
727 }
728 
729 /* Apply ................................................................... */
730 void POCSClass::apply(GridVolume &vol_basis, int it, int images)
731 {
732  Image<double> vol_POCS, theo_POCS_vol, corr_POCS_vol, vol_voxels;
733 
734  if (apply_POCS && POCS_i % POCS_freq == 0)
735  {
736  Image<double> vol_aux;
737  Image<double> *desired_volume = nullptr;
738 
739  // Compute the corresponding voxel volume
740  prm->basis.changeToVoxels(vol_basis, &(vol_voxels()),
743  {
744  vol_voxels.write("PPPvolPOCS0.vol");
745  std::cout << "Stats PPPvolPOCS0.vol: ";
746  vol_voxels().printStats();
747  std::cout << std::endl;
748  }
749  // Apply surface restriction
750  if (prm->surface_mask != nullptr)
751  {
752  vol_POCS() = (*(prm->surface_mask))();
753  }
754  else
755  {
756  vol_POCS().resize(vol_voxels());
757  vol_POCS().initZeros();
758  }
760  {
761  vol_POCS.write("PPPvolPOCS1.vol");
762  std::cout << "Stats PPPvolPOCS1.vol: ";
763  vol_POCS().printStats();
764  std::cout << std::endl;
765  }
766  // Force symmetry
767  if (prm->force_sym != 0)
768  {
769  symmetrizeVolume(prm->SL, vol_voxels(), vol_aux());
770  desired_volume = &vol_aux;
772  {
773  vol_aux.write("PPPvolPOCS2.vol");
774  std::cout << "Stats PPPvolPOCS2.vol: ";
775  vol_aux().printStats();
776  std::cout << std::endl;
777  }
778  }
779  // Apply volume constraint
780  if (prm->known_volume != -1)
781  {
782  Histogram1D hist;
783  MultidimArray<int> aux_mask;
784  aux_mask.resize(vol_POCS());
786  aux_mask(k, i, j) = 1 - (int)vol_POCS(k, i, j);
787  long mask_voxels = vol_POCS().countThreshold("below", 0.5, 0);
789  aux_mask, vol_voxels(), hist, 300);
790  double known_percentage;
791  known_percentage = XMIPP_MIN(100, 100 * prm->known_volume / mask_voxels);
792  double threshold;
793  threshold = hist.percentil(100 - known_percentage);
794  FOR_ALL_ELEMENTS_IN_ARRAY3D(vol_voxels())
795  if (vol_voxels(k, i, j) < threshold)
796  vol_POCS(k, i, j) = 1;
797  }
799  {
800  vol_POCS.write("PPPvolPOCS3.vol");
801  std::cout << "Stats PPPvolPOCS3.vol: ";
802  vol_POCS().printStats();
803  std::cout << std::endl;
804  }
805 
806  // Do not allow positivity outside interest region
807  // and do not allow negativity inside the interest region
808  // if positivity restrictions are to be applied
809  // int bg = (int) vol_POCS().sum();
810  // int fg = MULTIDIM_SIZE(vol_POCS()) - bg;
811  int relax = 0, posi = 0;
812  const MultidimArray<double> &mVolVoxels=vol_voxels();
813  const MultidimArray<double> &mVolPOCS=vol_POCS();
815  if (DIRECT_A3D_ELEM(mVolPOCS,k, i, j) == 1 && DIRECT_A3D_ELEM(mVolVoxels,k, i, j) < 0)
816  {
817  DIRECT_A3D_ELEM(mVolPOCS,k, i, j) = 0;
818  relax++;
819  }
820  else if (DIRECT_A3D_ELEM(mVolPOCS,k, i, j) == 0 && DIRECT_A3D_ELEM(mVolVoxels,k, i, j) < 0 && prm->positivity)
821  {
822  DIRECT_A3D_ELEM(mVolPOCS,k, i, j) = 1;
823  posi++;
824  }
825  // Debugging messages
826  //std::cout << "Relaxation/Positivity " << (double)relax/(double)bg << " "
827  // << (double)posi/(double)fg << " " << std::endl;
828 
829  // Solve volumetric equations
830  switch (prm->basis.type)
831  {
832  case Basis::blobs:
833  if (desired_volume == nullptr)
834  ART_voxels2blobs_single_step(vol_basis, &vol_basis,
835  prm->basis.blob, prm->D, prm->lambda(it),
836  &(theo_POCS_vol()), nullptr,
837  &(corr_POCS_vol()),
838  &(vol_POCS()),
839  POCS_mean_error, POCS_max_error, VARTK);
840  else
841  {
842  FOR_ALL_ELEMENTS_IN_ARRAY3D(vol_POCS())
843  if (vol_POCS(k, i, j) == 1)
844  (*desired_volume)(k, i, j) = 0;
845  for (int i = 0; i < prm->force_sym; i++)
846  {
847  ART_voxels2blobs_single_step(vol_basis, &vol_basis,
848  prm->basis.blob, prm->D, prm->lambda(it),
849  &(theo_POCS_vol()), &((*desired_volume)()),
850  &(corr_POCS_vol()),
851  nullptr,
852  POCS_mean_error, POCS_max_error, VARTK);
854  std::cout << " POCS Iteration " << i
855  << " POCS Error=" << POCS_mean_error << std::endl;
856  }
857  }
858  break;
859  case Basis::voxels:
860  if (desired_volume == nullptr)
861  {
862  FOR_ALL_ELEMENTS_IN_ARRAY3D(vol_POCS())
863  if (vol_POCS(k, i, j))
864  vol_basis(0)(k, i, j) = 0;
865  }
866  else
867  {
868  vol_basis(0)().initZeros();
869  FOR_ALL_ELEMENTS_IN_ARRAY3D((*desired_volume)())
870  vol_basis(0)(k, i, j) = (*desired_volume)(k, i, j);
871  }
872  POCS_mean_error = -1;
873  break;
874  default:
875  REPORT_ERROR(ERR_ARG_INCORRECT,"This function cannot work with this basis");
876  }
877  POCS_i = 1;
878  POCS_global_mean_error += POCS_mean_error;
879  POCS_N++;
880 
881  // Now some control logic
882  if (prm->numIMG - images < 100 || images % 100 == 0 ||
883  desired_volume != nullptr)
884  {
885  POCS_freq = 1;
886  POCS_state = POCS_measuring;
887  POCS_vec_i = 0;
888  }
889  else
890  {
891  double dummy;
892  switch (POCS_state)
893  {
894  case POCS_measuring:
895 #ifdef DEBUG_POCS
896 
897  std::cout << "M:" << POCS_vec_i << " " << POCS_mean_error << std::endl;
898 #endif
899 
900  POCS_errors(POCS_vec_i++) = POCS_mean_error;
901  if (POCS_vec_i == POCS_N_measure)
902  {
903  POCS_vec_i = 0;
904  // Change to use state
905  POCS_used = 0;
906  POCS_freq++;
907  POCS_state = POCS_use;
908 #ifdef DEBUG_POCS
909 
910  std::cout << "1: Changing to " << POCS_freq << std::endl;
911 #endif
912 
913  }
914  break;
915  case POCS_use:
916  POCS_used++;
917  POCS_errors.computeStats(POCS_avg,
918  POCS_stddev, dummy, POCS_min);
919 #ifdef DEBUG_POCS
920 
921  std::cout << "Reference errors: " << POCS_errors.transpose() << std::endl;
922  std::cout << "Checking " << ABS(POCS_mean_error - POCS_avg) << " " << 1.2*1.96*POCS_stddev << std::endl;
923 #endif
924 
925  if (ABS(POCS_mean_error - POCS_avg) < 1.2*1.96*POCS_stddev)
926  {
927  if (POCS_mean_error < POCS_avg)
928  {
929  double max_error = POCS_errors(0);
930  POCS_vec_i = 0;
931  for (int i = 1; i < POCS_N_measure; i++)
932  if (POCS_errors(i) > max_error)
933  {
934  max_error = POCS_errors(i);
935  POCS_vec_i = i;
936  }
937  POCS_errors(POCS_vec_i) = POCS_mean_error;
938  }
939  if (POCS_used < POCS_N_use)
940  { // While not enough uses
941  }
942  else if (POCS_freq < 3)
943  { // increase frequency
944  POCS_freq++;
945 #ifdef DEBUG_POCS
946 
947  std::cout << "2: Changing to " << POCS_freq << std::endl;
948 #endif
949 
950  POCS_used = 0;
951  }
952  }
953  else
954  {
955  // It is behaving worse
956  if (POCS_freq > prm->POCS_freq + 1)
957  {
958  POCS_freq = prm->POCS_freq + 1;
959  POCS_used = 0;
960 #ifdef DEBUG_POCS
961 
962  std::cout << "3: Changing to " << POCS_freq << std::endl;
963 #endif
964 
965  }
966  else if (POCS_used > 2)
967  {
968  POCS_freq = prm->POCS_freq;
969  // Change status
970  POCS_used = 0;
971  POCS_state = POCS_lowering;
972 #ifdef DEBUG_POCS
973 
974  std::cout << "Lowering\n";
975 #endif
976 
977  }
978  }
979  break;
980  case POCS_lowering:
981  // Lower the POCS error before measuring again
982  POCS_errors.computeStats(POCS_avg,
983  POCS_stddev, POCS_max, dummy);
984  POCS_used++;
985  if (POCS_mean_error < POCS_max || POCS_used > 2*POCS_N_measure)
986  {
987  // Change status
988  POCS_vec_i = 0;
989  POCS_state = POCS_measuring;
990  }
991  break;
992  default:
993  REPORT_ERROR(ERR_ARG_INCORRECT,"Unknown equation mode");
994  }
995  }
996  }
997  else
998  {
999  POCS_i++;
1000  POCS_mean_error = -1;
1001  }
1002 }
1003 
bool is_crystal
Is this a crystal 0 means NO 1 YES.
Definition: basic_art.h:252
Just to locate unclassified errors.
Definition: xmipp_error.h:192
void init_progress_bar(long total)
MDRowVec row
Header information of projection.
Definition: basic_art.h:63
void selfWindow(int n0, int z0, int y0, int x0, int nF, int zF, int yF, int xF, T init_value=0)
bool positivity
Apply positivity constraint.
Definition: basic_art.h:246
int numIMG
Total number of images to process (taking symmetries into account)
Definition: basic_art.h:348
int * nmax
Rotation angle of an image (double,degrees)
#define YSIZE(v)
void Bilib_DWT(const MultidimArray< double > &input, MultidimArray< double > &result, int iterations, int isign)
Definition: wavelet.cpp:43
#define POCS_N_measure
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
#define XMIPP_MAX(x, y)
Definition: xmipp_macros.h:193
size_t projXdim
Projection X dimension.
Definition: basic_art.h:333
#define GET_RESULTS(fh, fn, avg, cov, N, idx)
double psi
Psi angle.
Definition: basic_art.h:71
#define TELL_SHOW_ERROR
Definition: basic_art.h:272
void getMatrices(int i, Matrix2D< double > &L, Matrix2D< double > &R, bool homogeneous=true) const
Definition: symmetries.cpp:348
Basis basis
Basis function. By default, blobs.
Definition: basic_art.h:97
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
void resize(const Matrix1D< double > &corner1, const Matrix1D< double > &corner2)
Definition: grids.h:873
size_t size() const
Definition: matrix1d.h:508
void updateResidualVector(BasicARTParameters &prm, GridVolume &vol_basis, double &kappa, double &pow_residual_vol, double &pow_residual_imgs)
void fromVector(const Matrix1D< T > &op1)
Definition: matrix2d.cpp:803
void apply_binary_mask(const MultidimArray< int > &mask, const MultidimArray< T > &m_in, MultidimArray< T > &m_out, T subs_val=(T) 0)
Definition: mask.h:857
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY2D(m)
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
doublereal * c
#define MULTIDIM_SIZE(v)
#define dAij(M, i, j)
void symmetrizeVolume(const SymList &SL, const MultidimArray< double > &V_in, MultidimArray< double > &V_out, int spline, bool wrap, bool do_outside_avg, bool sum, bool helical, bool dihedral, bool helicalDihedral, double rotHelical, double rotPhaseHelical, double zHelical, double heightFraction, const MultidimArray< double > *mask, int Cn)
Definition: symmetrize.cpp:117
void sqrt(Image< double > &op)
void BinaryCircularMask(MultidimArray< int > &mask, double radius, int mode, double x0, double y0, double z0)
Definition: mask.cpp:193
Matrix2D< double > * D
Definition: basic_art.h:365
Tilting angle of an image (double,degrees)
void ART_voxels2blobs_single_step(GridVolume &vol_in, GridVolume *vol_out, const struct blobtype &blob, const Matrix2D< double > *D, double lambda, MultidimArray< double > *theo_vol, const MultidimArray< double > *read_vol, MultidimArray< double > *corr_vol, const MultidimArray< double > *mask_vol, double &mean_error, double &max_error, int eq_mode, int threads)
Definition: blobs.cpp:1094
constexpr int VARTK
Definition: blobs.h:378
There is not enough memory for allocation.
Definition: xmipp_error.h:166
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)
#define A1D_ELEM(v, i)
void newIteration()
Start New ART iteration.
void inv(Matrix2D< T > &result) const
Definition: matrix2d.cpp:663
Special label to be used when gathering MDs in MpiMetadataPrograms.
struct blobtype blob
Blob parameters.
Definition: basis.h:61
#define BACKWARD
Definition: blobs.cpp:1092
Name for the CTF Model (std::string)
POCSClass(BasicARTParameters *_prm, int _Zoutput_volume_size, int _Youtput_volume_size, int _Xoutput_volume_size)
Constructor.
double percentil(double percent_mass)
Definition: histogram.cpp:160
void newProjection()
Start new Projection.
Matrix2D< T > transpose() const
Definition: matrix2d.cpp:1314
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY3D(V)
tBasisFunction type
Basis function to use.
Definition: basis.h:52
int symsNo() const
Definition: symmetries.h:268
virtual IdIteratorProxy< false > ids()
std::vector< MultidimArray< double > > VA
Vector of training vectors.
Definition: recons_misc.h:88
size_t projYdim
Projection Y dimension.
Definition: basic_art.h:336
void Euler_apply_transf(const Matrix2D< double > &L, const Matrix2D< double > &R, double rot, double tilt, double psi, double &newrot, double &newtilt, double &newpsi)
Definition: geometry.cpp:1038
#define STARTINGX(v)
void changeToVoxels(GridVolume &vol_basis, MultidimArray< double > *vol_voxels, int Zdim, int Ydim, int Xdim, int threads=1) const
Definition: basis.cpp:261
size_t size() const override
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
Matrix1D< T > transpose() const
Definition: matrix1d.cpp:644
void initLinear(T minF, T maxF, int n=1, const String &mode="incr")
#define STARTINGY(v)
void threshold(double *phi, unsigned long nvox, double limit)
Definition: lib_vwk.cpp:524
double rnd_unif()
double known_volume
Known volume. If -1, not applied.
Definition: basic_art.h:226
#define EULER_CLIPPING(rot, tilt, psi)
Definition: geometry.h:471
#define FOR_ALL_ELEMENTS_IN_ARRAY3D(V)
double tilt
Tilting angle.
Definition: basic_art.h:69
GridVolumeT< int > * GVNeq
Definition: basic_art.h:381
void sortRandomly(int numIMG, MultidimArray< int > &ordered_list)
void project_GridVolume(GridVolumeT< T > &vol, const Basis &basis, Projection &proj, Projection &norm_proj, int Ydim, int Xdim, double rot, double tilt, double psi, int FORW, int eq_mode, GridVolumeT< int > *GVNeq, Matrix2D< double > *M, const MultidimArray< int > *mask, double ray_length, int threads)
Incorrect argument received.
Definition: xmipp_error.h:113
size_t firstRowId() const override
ReconsInfo * IMG_Inf
Array with all the sorting information for each projection.
Definition: basic_art.h:342
int seed
Definition: basic_art.h:81
void initZeros()
Definition: grids.h:936
#define XSIZE(v)
void progress_bar(long rlen)
void newUpdateVolume(GridVolume *ptr_vol_out, Projection &read_proj)
#define ABS(x)
Definition: xmipp_macros.h:142
FileName fn_ctf
CTF filename.
Definition: basic_art.h:65
#define ZSIZE(v)
double z
#define ROUND(x)
Definition: xmipp_macros.h:210
#define POCS_N_use
double dummy
FileName fn_root
Definition: basic_art.h:217
FileName fn_proj
Projection filename.
Definition: basic_art.h:61
void sortPerpendicular(int numIMG, ReconsInfo *IMG_Inf, MultidimArray< int > &ordered_list, int N)
#define DIRECT_A3D_ELEM(v, k, i, j)
#define XMIPP_MIN(x, y)
Definition: xmipp_macros.h:181
#define MAXFLOAT
Definition: data_types.h:47
void svdcmp(const Matrix2D< T > &a, Matrix2D< double > &u, Matrix1D< double > &w, Matrix2D< double > &v)
Definition: matrix2d.cpp:125
#define j
#define FORWARD
Definition: blobs.cpp:1091
int force_sym
Force the reconstruction to be symmetric this number of times.
Definition: basic_art.h:196
bool getValue(MDObject &mdValueOut, size_t id) const override
BasicARTParameters * prm
Definition: recons_misc.h:85
File cannot be open.
Definition: xmipp_error.h:137
VariabilityClass(BasicARTParameters *_prm, int _Zoutput_volume_size, int _Youtput_volume_size, int _Xoutput_volume_size)
Constructor.
void apply(GridVolume &vol_basis, int it, int images)
Apply.
void SelectDWTBlock(int scale, const MultidimArray< T > &I, const std::string &quadrant, int &x1, int &x2)
Definition: wavelet.h:134
void setRow(size_t i, const Matrix1D< T > &v)
Definition: matrix2d.cpp:910
MultidimArray< int > ordered_list
Order in which projections will be presented to algorithm.
Definition: basic_art.h:345
double rot
Rotational angle.
Definition: basic_art.h:67
T dotProduct(const Matrix1D< T > &v1, const Matrix1D< T > &v2)
Definition: matrix1d.h:1140
void typeCast(const Matrix1D< T1 > &v1, Matrix1D< T2 > &v2)
Definition: matrix1d.h:1227
#define TELL_SAVE_AT_EACH_STEP
Definition: basic_art.h:274
Image< double > * surface_mask
Definition: basic_art.h:371
MDRowVec getRowVec(size_t id)
void noSort(int numIMG, MultidimArray< int > &ordered_list)
t_VAR_status VAR_state
Definition: recons_misc.h:81
void initZeros()
Definition: matrix2d.h:626
ProgClassifyCL2D * prm
void setAngles(double _rot, double _tilt, double _psi)
void initZeros(const MultidimArray< T1 > &op)
void detach() override
unsigned int randomize_random_generator()
bool containsLabel(const MDLabel label) const override
#define SYMINDEX(SL, sym_no, i, numIMG)
Definition: symmetries.h:110
int N
Number of updates so far.
Definition: recons_misc.h:91
double lambda(int n)
Definition: basic_art.h:438
void buildReconsInfo(MetaDataVec &selfile, const FileName &fn_ctf, const SymList &SL, ReconsInfo *&IMG_Inf, bool do_not_use_symproj)
Definition: recons_misc.cpp:37
void getRow(size_t i, Matrix1D< T > &v) const
Definition: matrix2d.cpp:871
int threads
Number of threads to use. Can not be different than 1 when using MPI.
Definition: basic_art.h:267
#define STARTINGZ(v)
int * n
Name of an image (std::string)
void resize(size_t Ydim, size_t Xdim, bool noCopy=false)
Definition: matrix2d.cpp:1022
void compute_hist_within_binary_mask(const MultidimArray< int > &mask, MultidimArray< T > &v, Histogram1D &hist, int no_steps)
Definition: mask.h:906
void clear()
Definition: xmipp_image.h:144
SymList SL
A list with the symmetry matrices.
Definition: basic_art.h:330
#define NFEATURES
std::vector< Projection > residual_imgs
Definition: basic_art.h:135
constexpr int INNER_MASK
Definition: mask.h:47