Xmipp  v3.23.11-Nereus
ml_refine3d.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Sjors Scheres scheres@cnb.csic.es (2004)
4  *
5  * Unidad de Bioinformatica del 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 "ml_refine3d.h"
27 
28 #include "core/metadata_sql.h"
29 #include "core/xmipp_image.h"
31 #include "core/xmipp_log.h"
32 #include "data/morphology.h"
34 #include "data/projection.h"
35 #include "reconstruct_art.h"
36 #include "reconstruct_fourier.h"
37 #include "data/fourier_filter.h"
38 #include "mlf_align2d.h"
39 #include "ml_align2d.h"
40 #include "symmetrize.h"
41 #include "volume_segment.h"
42 
43 //#define DEBUG
44 //Macro to obtain the iteration base name
45 #define FN_ITER(iter, suffix) formatString("%sextra/iter%03d/%s",fn_root.c_str(), (iter), (suffix))
46 #undef FN_ITER_BASE
47 #define FN_ITER_BASE(iter) FN_ITER(iter, "vol")
48 #define FN_INITIAL_BASE FN_ITER_BASE(0)
49 #define FN_PROJECTIONS_MD FN_EXTRA("projections.xmd")
50 #define FN_PROJECTIONS FN_EXTRA("projections.stk")
51 
52 #define FN_NOISE_VOLBASE FN_EXTRA("noise_vol")
53 #define FN_CREF_VOLBASE FN_EXTRA("cref_vol")
54 // Filename generation for a volume from a base
55 #define COMPOSE_VOL_FN(fn, volno, base) fn.compose(base, volno, "vol")
56 
57 
59 {
60  fourier_mode = fourier;
61  if (fourier)
62  ml2d = new ProgMLF2D();
63  else
64  ml2d = new ProgML2D();
65  rank = 0;
66  size = 1;
67 }
68 
70 {
71  CLOSE_LOG();
72  delete ml2d;
73 }
74 
75 // Usage ===================================================================
77 {
78  addUsageLine("Separate structurally heterogeneous data sets into homogeneous classes by a");
79  addUsageLine("multi-reference 3D-angular refinement using a maximum-likelihood(ML) target function.");
80  //Add some params from 2D
81  //Setting some flags for the params definitions
82  ml2d->defaultNiter = 25;
83  ml2d->referenceExclusive = false;
84  ml2d->allowFastOption = false;
85  ml2d->allowRestart = false;
86  ml2d->allowIEM = true;
87 
88  //basic params
89  ml2d->defineBasicParams(this);
90  addParamsLine(" [ --ang <float=10> ] : Angular sampling (degrees) ");
91  //extra params
92  ml2d->defineAdditionalParams(this, "==+ ML additional options: ==");
93  addParamsLine("==+ Additional options: ==");
94  addParamsLine("--recons <recons_type=wlsART> : Reconstruction method to be used");
95  addParamsLine(" where <recons_type> ");
96  addParamsLine(" wlsART <params=\"\"> : wlsART parameters");
97  addParamsLine(" fourier <params=\"\"> : fourier parameters");
98  addParamsLine(" [ --nostart ] : Start wlsART reconstructions from all-zero volumes ");
99  addParamsLine(" [ --sym <symfile=c1> ] : Symmetry group ");
100  addParamsLine(" [ --low_pass <freq=-1> ] : Low-pass filter volume every iteration ");
101  addParamsLine(" [ --sym_mask <maskfile=\"\"> ] : Local symmetry (only inside mask) ");
102  addParamsLine(" [ --tilt <min=0> <max=180> ] : Minimum and maximum values for restriction tilt angle search ");
103  addParamsLine(" [ --perturb ] : Randomly perturb reference projection directions ");
104  //hidden params
105  ml2d->defineHiddenParams(this);
106  addParamsLine(" [--solvent <filename=\"\">]");
107  addParamsLine(" [--prob_solvent]");
108  addParamsLine(" [--threshold_solvent <float=999.>]");
109  addParamsLine(" [--deblob_solvent]");
110  addParamsLine(" [--dilate_solvent <int=0>]");
111  addParamsLine(" [--skip_reconstruction]");
112 }
113 
114 // Read ===================================================================
116 {
117  bool do_restart = false;
118 
119  // Generate new command line for restart procedure
121  /*
122  if (checkParam( "-restart"))
123 {
124  String comment, cline = "";
125  DocFile DFi;
126  FileName fn_tmp;
127 
128  do_restart = true;
129  DFi.read(getParameter(argc, argv, "-restart"));
130  DFi.go_beginning();
131  comment = (DFi.get_current_line()).get_text();
132  if (fourier_mode && strstr(comment.c_str(), "MLFalign2D-logfile") == NULL)
133  {
134  std::cerr << "Error!! Docfile is not of MLFalign2D-logfile type. " << std::endl;
135  exit(1);
136  }
137  else if (!fourier_mode && strstr(comment.c_str(), "MLalign2D-logfile") == NULL)
138  {
139  std::cerr << "Error!! Docfile is not of MLalign2D-logfile type. " << std::endl;
140  exit(1);
141  }
142  else
143  {
144  char *copy;
145  copy = NULL;
146  DFi.next();
147  // get new part of command line (with -istart)
148  comment = (DFi.get_current_line()).get_text();
149  DFi.next();
150  // get original command line
151  cline = (DFi.get_current_line()).get_text();
152  comment = comment + cline;
153  // regenerate command line
154  argv2 = NULL;
155  argc2 = 0;
156  generateCommandLine(comment, argc2, argv2, copy);
157  // Get number of volumes and names to generate SFvol
158  if (fourier_mode)
159  fn_root = getParam( "-o", "mlf3d");
160  else
161  fn_root = getParam( "-o", "ml3d");
162  fn_vol = getParam( "-vol");
163  istart = getIntParam( "-istart"));
164  if (Is_VolumeXmipp(fn_vol))
165  {
166  SFvol.clear();
167  SFvol.addObject();
168  SFvol.setValue(MDL_IMAGE, fn_vol);
169  SFvol.setValue(MDL_ENABLED, 1);
170  }
171  else
172  {
173  SFvol.read(fn_vol);
174  }
175  SFvol.removeObjects(MDValueEQ(MDL_ENABLED, -1));
176  Nvols = SFvol.size();
177 
178  SFvol.clear();
179  for (int ivol = 0; ivol < Nvols; ivol++)
180  {
181  fn_tmp = fn_root + "_it";
182  fn_tmp.compose(fn_tmp, istart - 1, "");
183  if (Nvols > 1)
184  {
185  fn_tmp += "_vol";
186  fn_tmp.compose(fn_tmp, ivol + 1, "");
187  }
188  fn_tmp += ".vol";
189  SFvol.addObject();
190  SFvol.setValue(MDL_IMAGE, fn_tmp);
191  SFvol.setValue(MDL_ENABLED, 1):
192  }
193  fn_vol = fn_root + "_it";
194  fn_vol.compose(fn_vol, istart - 1, "");
195  fn_vol += "_restart.sel";
196  SFvol.write(fn_vol);
197  }
198 }
199  else
200 {
201  */
202  // no restart, just copy argc to argc2 and argv to argv2
203  //argc2 = argc;
204  //argv2 = argv;
205  // }
206 
207 
208  //Read Refine3d parameters
209  fn_sel = getParam( "-i");
210  fn_root = getParam("--oroot");
211 
212 
213  // if (fourier_mode)
214  // fn_root = getParam( "-o", "mlf3d");
215  // else
216  // fn_root = getParam( "-o", "ml3d");
217 
218  if (!do_restart)
219  {
220  // Fill volume selfile
221  fn_ref = getParam( "--ref");
222  mdVol.read(fn_ref);
223  Nvols = mdVol.size();
224  }
225 
226  angular = getDoubleParam( "--ang");
227  fn_sym = getParam( "--sym");
228  eps = getDoubleParam( "--eps");
229  Niter = getIntParam( "--iter");
230  istart = 1;//getIntParam( "-istart");
231  tilt_range0 = getDoubleParam( "--tilt", 0);
232  tilt_rangeF = getDoubleParam( "--tilt", 1);
233  fn_symmask = getParam( "--sym_mask");
234  lowpass = getDoubleParam( "--low_pass");
235 
236  wlsart_no_start = checkParam( "--nostart");
237  // if (checkParam("--wlsart"))
238  // {
239  // wlsart_lambda = getDoubleParam("--wlsart", 0);
240  // wlsart_kappa = getDoubleParam("--wlsart", 1);
241  // wlsart_Niter = getIntParam("--wlsart", 2);
242  // }
243  do_perturb = checkParam( "--perturb");
244 
245  // Hidden for now
246  fn_solv = getParam( "--solvent");
247 
248  if (STR_EQUAL(getParam("--recons"), "wlsART"))
250  else if (STR_EQUAL(getParam("--recons"), "fourier"))
252 
253  do_prob_solvent = checkParam( "--prob_solvent");
254  threshold_solvent = getDoubleParam( "--threshold_solvent");
255  do_deblob_solvent = checkParam( "--deblob_solvent");
256  dilate_solvent = getIntParam( "--dilate_solvent");
257  skip_reconstruction = checkParam( "--skip_reconstruction");
258 
259  // Checks
260  if (lowpass > 0.5)
261  REPORT_ERROR(ERR_VALUE_INCORRECT, "Digital frequency for low-pass filter should be smaller than 0.5");
262 
263  //Read ml2d params
264  ml2d->do_ML3D = true;
265  ml2d->verbose = verbose; // 2d inherits verbosity from 3d
266  ml2d->read(argc, argv, false);
267 
268  if (!checkParam("--psi_step"))
269  ml2d->psi_step = angular;
270 
271  ml2d->fn_img = fn_sel;
274  ml2d->do_mirror = true;
275 
276  //add empty string string now, this will be later
277  //overwrite with the iteration base name
278  reconsOutFnBase.push_back("");
279  reconsMdFn.push_back("");
280 
281  if (fourier_mode)
282  {
283  //For fourier case add also the _noise and _cref
284  reconsOutFnBase.push_back(FN_CREF_VOLBASE);
286  {//make fn_root local scope
287  String fn_root = this->fn_root + ml2d->defaultRoot; // this is need for the following macro
288  reconsMdFn.push_back(FN_CREF_IMG_MD);
289  }
290  reconsMdFn.push_back(FN_NOISE_IMG_MD);
291 
292  }
293  CREATE_LOG(LOG_FN(fn_root));
294 }
295 
297 {
298  LOG_FUNCTION();
299 
300  if (verbose == 0)
301  return;
302 
303  std::cout << " -----------------------------------------------------------------" << std::endl;
304  std::cout << " | Read more about this program in the following publication: |" << std::endl;
305  if (fourier_mode)
306  std::cout << " | Scheres ea. (2007) Structure, 15, 1167-1177 |" << std::endl;
307  else
308  std::cout << " | Scheres ea. (2007) Nature Methods, 4, 27-29 |" << std::endl;
309  std::cout << " | |" << std::endl;
310  std::cout << " | *** Please cite it if this program is of use to you! *** |" << std::endl;
311  std::cout << " -----------------------------------------------------------------" << std::endl;
312  std::cout << "--> Maximum-likelihood multi-reference 3D-refinement" << std::endl;
313  if (Nvols == 1)
314  std::cout << " Initial reference volume : " << fn_ref << std::endl;
315  else
316  {
317  std::cout << " Selfile with references : " << fn_ref << std::endl;
318  std::cout << " with # of volumes : " << Nvols << std::endl;
319  }
320  std::cout << " Experimental images: : " << fn_sel << std::endl;
321  std::cout << " Angular sampling rate : " << angular << std::endl;
322  std::cout << " Symmetry group: : " << fn_sym << std::endl;
323  if (fn_symmask != "")
324  std::cout << " Local symmetry mask : " << fn_symmask << std::endl;
325  std::cout << " Output rootname : " << fn_root << std::endl;
326  std::cout << " Convergence criterion : " << eps << std::endl;
327  if (lowpass > 0)
328  std::cout << " Low-pass filter : " << lowpass << std::endl;
329  if (tilt_range0 >= 0 || tilt_rangeF <= 180)
330  std::cout << " Limited tilt range : " << tilt_range0 << " " << tilt_rangeF << std::endl;
331  if (wlsart_no_start)
332  std::cout << " -> Start wlsART reconstructions from all-zero volumes " << std::endl;
334  std::cout << " -> Use fourier-interpolation instead of wlsART for reconstruction" << std::endl;
335  if (do_prob_solvent)
336  std::cout << " -> Perform probabilistic solvent flattening" << std::endl;
337  std::cout << " -----------------------------------------------------------------" << std::endl;
338 }
339 
341 {
342  LOG_FUNCTION();
343  FileName fn_sym_loc;
344  // Precalculate sampling
346  fn_sym_loc = fn_symmask.empty() ? fn_sym : "c1";
347 
348  if (!mysampling.SL.isSymmetryGroup(fn_sym_loc, symmetry, sym_order))
349  REPORT_ERROR(ERR_NUMERICAL, (String)"ml_refine3d::run Invalid symmetry" + fn_sym_loc);
350  mysampling.SL.readSymmetryFile(fn_sym_loc);
354 }
355 
356 // Fill sampling and create DFlib
358 {
359  LOG_FUNCTION();
360  //Create sampling
361  createSampling();
362  show();
363  // Write starting volume(s) to disc with correct name for iteration loop
364  copyVolumes();
365  // Project volumes and store projections in a metadata
367 // //FIXME: this is for concurrency problem...remove after that
368 // FileName myImg = fn_root + formatString("images_node%02d.xmd", rank);
369 // MetaData(fn_sel).write(myImg);
370 // ml2d->fn_img = myImg;
371  //2d initialization
372  LOG("before ml2d->produceSideInfo");
374 }
375 
377 {
378  LOG_FUNCTION();
381  ml2d->show();
382  Nvols *= ml2d->factor_nref;
383  ml2d->Iold.clear(); // To save memory
384 }
385 
387 {
388  LOG_FUNCTION();
389  bool converged = false;
390 
391 
392  // Get input parameters
393  produceSideInfo();
395  ml2d->createThreads();
396 
397  //Local image to read data
398  Image<double> img;
399  FileName fn;
400  bool doProject = false;
401 
402  // Loop over all iterations
403  for (ml2d->iter = ml2d->istart; !converged && ml2d->iter <= ml2d->Niter; ml2d->iter++)
404  {
405  iter = ml2d->iter; //keep updated the iter class variable
406 
407  //Make path for iterations result files
409 
410  if (verbose)
411  std::cout << formatString("--> 3D-EM volume refinement: iteration %d of %d", iter, Niter) << std::endl;
412 
413  LOG("==============================================");
414  LOG(formatString("ML3D: Iteration %d of %d", iter, Niter));
415  LOG_LEVEL(Iteration);
416 
418  {
419  LOG(formatString("ML3D: BEGIN BLOCK %d of %d", ml2d->current_block, ml2d->blocks));
420  LOG_LEVEL(Block);
421  // Project volumes, already done for first iteration, first block
422  if (doProject)// || ml2d->current_block > 0)
423  {
425  int refno = 0;
426 
427  // Read new references from disc (I could just as well keep them in memory, maybe...)
428  for (size_t objId : ml2d->MDref.ids())
429  {
430  ml2d->MDref.getValue(MDL_IMAGE, fn, objId);
431  img.read(fn);
432  img().setXmippOrigin();
433  ml2d->model.Iref[refno]() = img();
434  if (++refno == ml2d->model.n_ref) //avoid reading noise and c_ref projections
435  break;
436  }
437  }
438  LOG("Calling ML2D Expectation");
439  // Integrate over all images
440  ml2d->expectation();
441  LOG("Calling ML2D Maximization");
442  ml2d->maximization();
443 
444  //do not reconstruction on special iteration 0 until last block
445  if (iter > SPECIAL_ITER || ml2d->current_block == ml2d->blocks - 1)//last block
446  {
447 
448  LOG("Writing ML2D references");
449  // Write out 2D reference images (to be used in reconstruction)
451 
452  // Jump out before 3D reconstruction
453  // (Useful for some parallelization protocols)
455  exit(1);
456 
457  if (fourier_mode)
458  makeNoiseImages();
459  // Reconstruct new volumes from the reference images
460  //update the base name for current iteration
462  reconsMdFn[0] = ml2d->outRefsMd;
464  // Update the reference volume selection file
466  // post-process the volumes
468  doProject = true;
469  }
470  } // end loop blocks
471 
472  if (fourier_mode)
474 
475  // Check convergence
476  converged = checkConvergence();
477 
478  // End 2D iteration
479  LOG("Calling ml2d->endIteration");
480  ml2d->endIteration();
481  } // end loop iterations
482 
483  if (verbose)
484  {
485  std::cout << (converged ?
486  "--> Optimization converged!" :
487  "--> Optimization was stopped before convergence was reached!")
488  << std::endl;
489  }
490 
491  // Write converged output ML2D files
492  LOG("Calling ml2d->writeOutputFiles, OUT_FINAL");
494  ml2d->destroyThreads();
495 
496 }//end of function run
497 
499 {
500  size_t dim, idum, idumLong;
501  getImageSizeFromFilename(fn_sel, dim, idum, idum, idumLong);
502  Image<double> img;
503 
504  if (type == EMPTY_PROJECTIONS)
505  createEmptyFile(FN_PROJECTIONS, dim, dim, 1, Nvols*nr_projections, true);
506  // {
507  // img().initZeros(dim, dim);
508  // img.write(FN_PROJECTIONS, Nvols * nr_projections, true, WRITE_OVERWRITE);
509  // }
510  else if (type == EMPTY_VOLUMES)
511  {
512  img().initZeros(dim, dim, dim);
513  for (size_t i = 0; i < reconsOutFnBase.size(); ++i)
514  createEmptyFile(reconsOutFnBase[i], dim, dim, dim, Nvols, true);
515  //img.write(reconsOutFnBase[i], Nvols, true, WRITE_OVERWRITE);
516  }
517 }
518 
519 // Projection of the reference (blob) volume =================================
521 {
522 
523  LOG_FUNCTION();
524 
525  Image<double> vol;
526  FileName fn_base = FN_PROJECTIONS, fn_tmp;
527  Projection proj;
528  double rot, tilt, psi = 0.;
529  size_t nl, nr_dir, id, bar_step;
530  int volno;
531 
532  // Here all nodes fill SFlib and DFlib, but each node actually projects
533  // only a part of the projections. In this way parallellization is obtained
534  // Total number of projections
535  nl = Nvols * nr_projections;
536  bar_step = XMIPP_MAX(1, nl / 60);
537 
538  // Initialize projections output metadata
539  mdProj.clear();
540 
541  if (verbose)
542  {
543  std::cout << formatString("--> projecting %d volumes x %d projections...", Nvols, nr_projections) << std::endl;
544  //init_progress_bar(nl);
545  }
546 
548 
549  // Loop over all reference volumes
550  volno = nr_dir = 0;
551 
552  //std::cerr << "DEBUG_JM: ProgMLRefine3D::projectVolumes" <<std::endl;
553  auto idIter = mdVol.ids().begin();
554  for (size_t i = 0; i < Nvols; ++i)
555  {
556  mdVol.getValue(MDL_IMAGE, fn_tmp, *idIter);
557  //std::cerr << "DEBUG_JM: fn_tmp: " << fn_tmp << std::endl;
558  vol.read(fn_tmp);
559  vol().setXmippOrigin();
560  ++volno;
561 
562  for (int ilib = 0; ilib < nr_projections; ++ilib)
563  {
564  ++nr_dir;
565  fn_tmp.compose(nr_dir, fn_base);
568 
569  // Parallelization: each rank projects and writes a different direction
570  if (nr_dir % size == rank)
571  {
572  projectVolume(vol(), proj, vol().rowNumber(), vol().colNumber(), rot, tilt, psi);
573  //proj.setEulerAngles(rot, tilt, psi);
574  //std::cerr << formatString("DEBUG_JM: Proyecting vol: %s, rot: %f, tilt: %f, psi: %f", fn_tmp.c_str(), rot, tilt, psi) <<std::endl;
575  proj.write(fn_tmp);
576  //proj.write(formatString("%s_iter%d.stk", fn_tmp.c_str(), iter));
577  }
578 
579  id = mdProj.addObject();
580  mdProj.setValue(MDL_IMAGE, fn_tmp, id);
581  mdProj.setValue(MDL_ENABLED, 1, id);
582  mdProj.setValue(MDL_ANGLE_ROT, rot, id);
583  mdProj.setValue(MDL_ANGLE_TILT, tilt, id);
584  mdProj.setValue(MDL_ANGLE_PSI, psi, id);
585  mdProj.setValue(MDL_REF3D, volno, id);
586 
587  if (verbose && (nr_dir % bar_step == 0))
588  progress_bar(nr_dir);
589  }
590  ++idIter;
591  }
592 
593  if (verbose)
594  {
595  //progress_bar(nl);
596  std::cout << " -----------------------------------------------------------------" << std::endl;
597  }
598 
599  // Only the master write the complete SFlib
600  if (rank == 0)
601  {
602  fn_tmp = FN_PROJECTIONS_MD;
603  mdProj.write(fn_tmp);
604  //Just copying projections md for debugging
605  //fn_tmp.copyFile(formatString("%s_iter%d_projections.xmd", fn_root.c_str(), iter));
606  //Also copying projections stack
607  //FileName(FN_PROJECTIONS).copyFile(formatString("%s_iter%d_projections.stk", fn_root.c_str(), iter));
608  }
609 
610 }
611 
612 // Make noise images for 3D SSNR calculation ===================================
614 {
615 
616  Image<double> img;
617  std::vector<Image<double> > & Iref = ml2d->model.Iref;
618  FileName fn_noise(FN_NOISE_IMG), fn_img;
619  MetaDataVec mdNoise(ml2d->MDref);
620  int refno = 0;
621 
622  for (size_t objId : mdNoise.ids())
623  {
624  img = Iref[refno];
625  img().initZeros();
626  img().addNoise(0, 1, "gaussian");
627 
628  if (Iref[refno].weight() > 1.)
629  img() /= sqrt(Iref[refno].weight());
630  fn_img.compose(++refno, fn_noise);
631  img.write(fn_img);
632  mdNoise.setValue(MDL_IMAGE, fn_img, objId);
633  if (refno == ml2d->model.n_ref)
634  break;
635  }
636  fn_noise = FN_NOISE_IMG_MD;
637  mdNoise.write(fn_noise);
638 }
639 
641 {
642  //get reconstruction extra params
643  String arguments = getParam("--recons", 1) +
644  formatString(" -v 0 --thr %d -i %s -o %s", ml2d->threads, input.c_str(), output.c_str());
645  ProgReconsBase * program;
646 // std::cerr << "DEBUG_JM: ProgMLRefine3D::createReconsProgram" <<std::endl;
647 // std::cerr << "DEBUG_JM: arguments: " << arguments << std::endl;
648 // std::cerr << "DEBUG_JM: input: " << input << std::endl;
649 
651  {
652  program = new ProgRecFourier();
653  //force use of weights and the verbosity will be the same of this program
654  //-i and -o options are passed for avoiding errors, this should be changed
655  //when reconstructing
656  arguments += " --weight";
657  program->read(arguments);
658  return program;
659  }
660  else if (recons_type == RECONS_ART)//use of wlsArt
661  {
662  //REPORT_ERROR(ERR_NOT_IMPLEMENTED,"not implemented reconstruction through wlsArt");
663  program = new ProgReconsART();
664  FileName fn_tmp(arguments);
665  arguments += " --WLS";
666  if (fn_symmask.empty() && checkParam("--sym"))
667  arguments += " --sym " + fn_sym;
668  if (!fn_tmp.contains("-n "))
669  arguments += " -n 10";
670  if (!fn_tmp.contains("-l "))
671  arguments += " -l 0.2";
672  if (!fn_tmp.contains("-k "))
673  arguments += " -k 0.5";
674 
675  bool noise_vols = input.contains("_cref_") || input.contains("_noise_");
676  if (!noise_vols && !wlsart_no_start)
677  {
678  arguments += " --save_basis";
679  if (iter > 1)
680  {
681  String currIter = FN_ITER_BASE(iter);
682  String prevIter = FN_ITER_BASE(iter - 1);
683  arguments += " --start ";
684  arguments += output.replaceSubstring(currIter, prevIter).replaceExtension("basis");
685  }
686  }
687  program->read(arguments);
688  return program;
689  // if (fn_symmask != "")
690  // art_prm.fn_sym = "";
691 
692 
693  // BasicARTParameters art_prm;
694  // Plain_ART_Parameters dummy;
695  // GridVolume new_blobs;
696  // GridVolume start_blobs;
697  // if (verbose)
698  // std::cerr << "--> weighted least-squares ART reconstruction " << std::endl;
699  //
700  // // Read ART parameters from command line & I/O with outer loop of Refine3d
701  // art_prm.read(argc, argv);
702  // art_prm.WLS = true;
703  // if (fn_symmask != "")
704  // art_prm.fn_sym = "";
705  // if (!checkParam( "-n"))
706  // art_prm.no_it = 10;
707  // if (!checkParam( "-l"))
708  // {
709  // art_prm.lambda_list.resize(1);
710  // art_prm.lambda_list.initConstant(0.2);
711  // }
712  // if (!checkParam( "-k"))
713  // {
714  // art_prm.kappa_list.resize(1);
715  // art_prm.kappa_list.initConstant(0.5);
716  // }
717  // art_prm.fn_sel = "xxxx"; //fixme
718  // art_prm.fn_root = "xxxx";
719  // if (noise == 1 || noise == 2)
720  // {
721  // art_prm.fn_start = "";
722  // art_prm.tell = false;
723  // }
724  // else if (!wlsart_no_start)
725  // {
726  // art_prm.tell = TELL_SAVE_BASIS;
727  // art_prm.fn_start = fn_blob;
728  // }
729  // // Reconstruct using weighted least-squares ART
730  // Basic_ROUT_Art(art_prm, dummy, new_vol, new_blobs);
731  }
732  return nullptr;
733 }
734 
735 // Reconstruction using the ML-weights ==========================================
737 {
738  LOG_FUNCTION();
739 
740  FileName fn_vol, fn_vol_prev, fn_one;
741  MetaDataVec mdOne, mdProj, mdOutVols;
742  size_t id;
743 
744 
745  ProgReconsBase * reconsProgram;
746  int volno_index = 0;
747 
749 
750  for (size_t i = 0; i < reconsOutFnBase.size(); ++i)
751  {
752  for (int volno = 1; volno <= (int)Nvols; ++volno)
753  {
754  volno_index = Nvols * i + volno - 1;
755  String &fn_base = reconsOutFnBase[i];
756  COMPOSE_VOL_FN(fn_vol, volno, fn_base);
757  //for now each node reconstruct one volume
758  if (volno_index % size == rank)
759  {
760  //fn_vol.compose(volno, fn_base);
761  mdProj.read(reconsMdFn[i]);
762  fn_one.compose(fn_base, volno, "projections.xmd");
763  // Select only relevant projections to reconstruct
764  mdOne.importObjects(mdProj, MDValueEQ(MDL_REF3D, volno));
765  mdOne.write(fn_one);
766  // Set input/output for the reconstruction algorithm
767  reconsProgram = createReconsProgram(fn_one, fn_vol);
768  reconsProgram->run();
769  delete reconsProgram;
770  }
771  //Store output volumes, avoid noise and cref volumes
772  //Only need to be done by master node
773  if (i == 0 && rank == 0)
774  {
775  id = mdOutVols.addObject();
776  mdOutVols.setValue(MDL_IMAGE, fn_vol, id);
777  mdOutVols.setValue(MDL_ENABLED, 1, id);
778  }
779  }//for volno
780  }//for reconsOutFnBase
781 
782  if (rank == 0)
783  {
784  FileName fn = FN_ITER_VOLMD();
785  mdOutVols.write(fn);
786  }
787 
788 }
789 
791 {
792 
793  LOG_FUNCTION();
794 
795  MetaDataVec mdNoiseAll, mdNoiseOne;
797  Image<double> vol, nvol;
798  FileName fn_tmp, fn_tmp2;
799  MultidimArray<double> alpha_signal, alpha_noise, input_signal, avg_alphaS, avg_alphaN;
800  MultidimArray<double> alpha_T, alpha_N, Msignal, Maux, Mone, mask;
801  Projection proj;
802  size_t c, dim, idum;
803  size_t idumLong;
804  double volweight, weight, rot, tilt, psi = 0.;
805  Matrix1D<int> center(2);
806  MultidimArray<int> radial_count;
807 
808  // Read in noise reconstruction and calculate alpha's
809  mdNoiseAll.read(FN_NOISE_IMG_MD);
810  getImageSize(mdNoiseAll, dim, idum, idum, idumLong);
811 
812  center.initZeros();
813  proj().resize(dim, dim);
814  proj().setXmippOrigin();
815  mask.resize(dim, dim);
816  mask.setXmippOrigin();
817  RaisedCosineMask(mask, dim / 2 - 2, dim / 2);
818 
819  if (verbose)
820  {
821  std::cout << "--> calculating 3D-SSNR ..." << std::endl;
822  initProgress(mdNoiseAll.size());
823  }
824 
825  FileName fn_noise_base = FN_NOISE_VOLBASE;
826  FileName fn_cref_base = FN_CREF_VOLBASE;
827  double inv_dim2 = 1. / (double)(dim * dim);
828 
829  for (int volno = 1; volno <= (int)Nvols; ++volno)
830  {
831  COMPOSE_VOL_FN(fn_tmp, volno, fn_noise_base);
832  COMPOSE_VOL_FN(fn_tmp2, volno, fn_cref_base);
833 // fn_tmp.compose(volno, fn_noise_base);
834 // fn_tmp2.compose(volno, fn_cref_base);
835 
836  nvol.read(fn_tmp);
837  vol.read(fn_tmp2);
838  nvol().setXmippOrigin();
839  vol().setXmippOrigin();
840  Mone.resize(dim, dim);
841  Mone.initConstant(inv_dim2);
842  Mone.setXmippOrigin();
843 
844  mdNoiseOne.clear();
845  mdNoiseOne.importObjects(mdNoiseAll, MDValueEQ(MDL_REF3D, volno));
846  c = 0;
847  volweight = 0.;
848  bool first_time = true;
849 
850  for (size_t objId: mdNoiseOne.ids())
851  {
852  mdNoiseOne.getValue(MDL_WEIGHT, weight, objId);
853  mdNoiseOne.getValue(MDL_ANGLE_ROT, rot, objId);
854  mdNoiseOne.getValue(MDL_ANGLE_TILT, tilt, objId);
855 
856  // accumulate alpha denominator
857  SUM_INIT(alpha_N, Mone * weight);
858  // alpha nominator
859  projectVolume(nvol(), proj, dim, dim, rot, tilt, psi);
860  apply_cont_mask(mask, proj(), proj());
861  FourierTransform(proj(), Faux);
862  FFT_magnitude(Faux, Maux);
863  CenterFFT(Maux, true);
864  Maux.setXmippOrigin();
865  Maux *= Maux;
866  SUM_INIT(alpha_T, Maux * weight);
867  // input signal
868  projectVolume(vol(), proj, dim, dim, rot, tilt, psi);
869  apply_cont_mask(mask, proj(), proj());
870  FourierTransform(proj(), Faux);
871  FFT_magnitude(Faux, Maux);
872  CenterFFT(Maux, true);
873  Maux.setXmippOrigin();
874  Maux *= Maux;
875  SUM_INIT(Msignal, Maux * weight);
876  volweight += weight;
877  setProgress(++c);
878  first_time = false;
879  }
880 
881  alpha_T.setXmippOrigin();
882  alpha_N.setXmippOrigin();
883  Msignal.setXmippOrigin();
884  alpha_signal.initZeros();
885  alpha_noise.initZeros();
886  input_signal.initZeros();
887  radialAverage(alpha_T, center, alpha_signal, radial_count, true);
888  radialAverage(alpha_N, center, alpha_noise, radial_count, true);
889  radialAverage(Msignal, center, input_signal, radial_count, true);
890 
891 // std::cerr << "DEBUG_JM: alpha_T: " << alpha_T << std::endl;
892 // std::cerr << "DEBUG_JM: alpha_N: " << alpha_N << std::endl;
893 // std::cerr << "DEBUG_JM: Msignal: " << Msignal << std::endl;
894 
895  input_signal *= 1./volweight;
896 
897  // Calculate spectral_signal =input_signal/alpha!!
898  // Also store averages of alphaN and alphaS for output
900  {
901  dAi(input_signal, i) = (dAi(alpha_signal, i) > 0.) ? dAi(input_signal, i) * dAi(alpha_noise, i) / dAi(alpha_signal, i) : 0.;
902 
903  }
904 
905  if (volno == 1)
906  {
907  spectral_signal = input_signal;
908  avg_alphaN = alpha_noise;
909  avg_alphaS = alpha_signal;
910  }
911  else
912  {
913  spectral_signal += input_signal;
914  avg_alphaN += alpha_noise;
915  avg_alphaS += alpha_signal;
916  }
917  }
918  endProgress();
919 
920  double inv_Nvols = 1. / (double)Nvols;
921  spectral_signal *= inv_Nvols;
922  avg_alphaN *= inv_Nvols;
923  avg_alphaS *= inv_Nvols;
924 
925  if (verbose)
926  {
927  fn_tmp = getIterExtraPath(fn_root, iter) + "3dssnr.log";
928  std::ofstream out(fn_tmp.c_str(), std::ios::out);
929  out << "# signal 1/alpha alpha-S alpha-N" << std::endl;
930  FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY1D(spectral_signal)
931  {
932  if (i > 0 && i < dim / 2)
933  {
934  out.width(5);
935  out << integerToString(i);
936  out.width(10);
937  out << floatToString(DIRECT_A1D_ELEM(spectral_signal, i));
938  out.width(10);
939  out << floatToString(DIRECT_A1D_ELEM(avg_alphaN, i) / DIRECT_A1D_ELEM(avg_alphaS, i));
940  out.width(10);
941  out << floatToString(DIRECT_A1D_ELEM(avg_alphaS, i));
942  out.width(10);
943  out << floatToString(DIRECT_A1D_ELEM(avg_alphaN, i));
944  out << std::endl;
945  }
946  }
947  out.close();
948  }
949 }
950 
952 {
953  LOG_FUNCTION();
954  ImageGeneric img;
955  getIterExtraPath(fn_root, 0); //Create folder to store volume
956  FileName fn_vol, fn_base = FN_INITIAL_BASE;
957  size_t volno = 0;
958 
959  for (size_t objId : mdVol.ids())
960  {
961  mdVol.getValue(MDL_IMAGE, fn_vol, objId);
962  img.read(fn_vol);
963  //fn_vol.compose(++volno, fn_base);
964  COMPOSE_VOL_FN(fn_vol, ++volno, fn_base);
965  img.write(fn_vol);
966  mdVol.setValue(MDL_IMAGE, fn_vol, objId);
967  mdVol.setValue(MDL_ENABLED, 1, objId);
968  }
969 }
970 
972 {
973  LOG_FUNCTION();
974  FileName fn_vol, fn_base;
975  mdVol.clear();
976 
977  for (size_t i = 0; i < reconsOutFnBase.size(); ++i)
978  {
979  fn_base = reconsOutFnBase[i];
980  for (size_t volno = 1; volno <= Nvols; ++volno)
981  {
982  COMPOSE_VOL_FN(fn_vol, volno, fn_base);
983  //fn_vol.compose(volno, fn_base);
984  auto objId = mdVol.addObject();
985  mdVol.setValue(MDL_IMAGE, fn_vol, objId);
986  mdVol.setValue(MDL_ENABLED, objId);
987  }
988  }
989 }
990 
991 // Modify reference volume ======================================================
993 {
994  LOG_FUNCTION();
995 
996  ProgVolumeSegment segm_prm;
997  FileName fn_vol, fn_tmp;
998  Image<double> vol, Vaux, Vsymmask, Vsolv;
999  MultidimArray<int> mask3D;
1000  double in, out;
1001  Sampling locsampling;
1002 
1003  // Use local sampling because of symmask
1004  if (!locsampling.SL.isSymmetryGroup(fn_sym, symmetry, sym_order))
1005  REPORT_ERROR(ERR_NUMERICAL, (String)"ml_refine3d::run Invalid symmetry" + fn_sym);
1006  locsampling.SL.readSymmetryFile(fn_sym);
1007 
1008  if ( !(fn_sym == "c1" || fn_sym == "C1" ) || lowpass > 0 ||
1009  fn_solv != "" || do_prob_solvent || threshold_solvent != 999)
1010  {
1011  LOG_LEVEL(postProcessVolumes_IF);
1012 
1013  for (size_t objId : mdVol.ids())
1014  {
1015  mdVol.getValue(MDL_IMAGE, fn_vol, objId);
1016  // Read corresponding volume from disc
1017  LOG(" ProgMLRefine3D::postProcessVolumes READING vol");
1018  vol.read(fn_vol);
1019  vol().setXmippOrigin();
1020  // Store the original volume on disc
1021  fn_tmp = fn_vol;
1022  fn_tmp.insertBeforeExtension(".original");
1023  //fn_tmp = fn_vol + ".original";
1024  LOG(" ProgMLRefine3D::postProcessVolumes writing ORIGINAL vol");
1025  vol.write(fn_tmp);
1026 
1027  // Symmetrize if requested
1028  if (!fn_sym.empty())
1029  {
1030  LOG(" ProgMLRefine3D::postProcessVolumes applying SYMMETRY");
1031  Vaux().resize(vol());
1032  symmetrizeVolume(locsampling.SL, vol(), Vaux());
1033  // Read local symmetry mask if requested
1034  if (!fn_symmask.empty())
1035  {
1036  Vsymmask.read(fn_symmask);
1037  Vsymmask().setXmippOrigin();
1038  if (Vsymmask().computeMax() > 1. || Vsymmask().computeMin() < 0.)
1039  REPORT_ERROR(ERR_VALUE_INCORRECT, "ERROR: sym_mask should have values between 0 and 1!");
1041  {
1042  in = dAkij(Vsymmask(), k, i, j);
1043  out = 1. - in;
1044  dAkij(vol(), k, i, j) = out * dAkij(vol(), k, i, j) + in * dAkij(Vaux(), k, i, j);
1045  }
1046  Vsymmask.clear();
1047  }
1048  else
1049  {
1050  vol = Vaux;
1051  }
1052  Vaux.clear();
1053  }
1054 
1055  // Filtering the volume
1056  if (lowpass > 0)
1057  {
1058  LOG(" ProgMLRefine3D::postProcessVolumes applying LOWPASS");
1059  FourierFilter fmask;
1060  fmask.raised_w = 0.02;
1061  fmask.FilterShape = RAISED_COSINE;
1062  fmask.FilterBand = LOWPASS;
1063  fmask.w1 = lowpass;
1064  fmask.applyMaskSpace(vol());
1065  }
1066 
1067  // Different types of solvent flattening
1068  if (do_prob_solvent || !fn_solv.empty() || (threshold_solvent != 999))
1069  {
1070  LOG(" ProgMLRefine3D::postProcessVolumes applying SOLVENT");
1071  if (do_prob_solvent)
1072  {
1073  // A. Probabilistic solvent flattening
1074  // Write already processed volume to disc (for segment program)
1075  vol.write(fn_vol);
1076  segm_prm.read(argc, argv);
1077  segm_prm.fn_vol = fn_vol;
1078  segm_prm.fn_mask = fn_vol + ".solv";
1079  segm_prm.do_prob = true;
1080  segm_prm.show();
1081  segm_prm.produce_side_info();
1082  segm_prm.segment(Vsolv);
1083  }
1084  else if (threshold_solvent != 999)
1085  {
1086  // B. Perform flooding and separate_objects-like solvent mask
1087  Vsolv = vol;
1088  Vsolv().threshold("below", threshold_solvent, 0.);
1089  // The following is because binarize() seems buggy
1091  {
1092  if (dAkij(Vsolv(), k, i, j) != 0.)
1093  dAkij(Vsolv(), k, i, j) = 1.;
1094  }
1095  }
1096  else if (fn_solv != "")
1097  {
1098  // C. Read user-provided solvent mask from disc
1099  Vsolv.read(fn_solv);
1100  if (Vsolv().computeMax() > 1. || Vsolv().computeMin() < 0.)
1101  REPORT_ERROR(ERR_VALUE_INCORRECT, "ERROR: solvent mask should have values between 0 and 1!");
1102  }
1103  // Binarize Vsolv, avoiding buggy Vsolv().binarize()
1104  if (do_deblob_solvent || dilate_solvent > 0)
1105  {
1106  Vsolv().threshold("below", 0.5, 0.);
1107  // The following is because binarize() seems buggy
1109  {
1110  if (dAkij(Vsolv(), k, i, j) != 0.)
1111  dAkij(Vsolv(), k, i, j) = 1.;
1112  }
1113  }
1114  if (do_deblob_solvent)
1115  {
1116  int object_no;
1117  double nr_vox, max_vox = 0.;
1118  Image<double> label;
1119  object_no = labelImage3D(Vsolv(), label());
1120  max_vox = 0;
1121  for (int o = 0; o <= object_no; o++)
1122  {
1123  Vaux() = label();
1125  {
1126  Vaux(k, i, j) = Vaux(k, i, j) == o;
1127  }
1128  nr_vox = Vaux().sum();
1129  if (o != 0 && (nr_vox > max_vox))
1130  {
1131  max_vox = nr_vox;
1132  Vsolv() = Vaux();
1133  }
1134  }
1135  label.clear();
1136  }
1137  // Dilate solvent mask (only for binary masks)
1138  // Dilate several times, result is summed iteratively
1139  if (dilate_solvent > 0)
1140  {
1141  Image<double> Vsum;
1142  Vsum() = Vsolv();
1143  for (int i = 0; i < dilate_solvent; i++)
1144  {
1145  dilate3D(Vsolv(), Vaux(), 18, 0, 1);
1146  Vsum() = Vsum() + Vaux();
1147  Vsolv() = Vaux();
1148  }
1149  Vsum() /= (double)(dilate_solvent + 1);
1150  Vsolv() = Vsum();
1151  Vsum.clear();
1152  }
1153  // Apply solvent mask
1154  Vsolv() = 1. - Vsolv();
1155  double solvavg = 0., sumsolv = 0.;
1157  {
1158  solvavg += dAkij(Vsolv(), k, i, j) * dAkij(vol(), k, i, j);
1159  sumsolv += dAkij(Vsolv(), k, i, j);
1160  }
1161  solvavg /= sumsolv;
1163  {
1164  dAkij(vol(), k, i, j) -= dAkij(Vsolv(), k, i, j) * (dAkij(vol(), k, i, j) - solvavg);
1165  }
1166  }
1167 
1168  // (Re-) write post-processed volume to disc
1169  LOG("Before WRITING vol");
1170  vol.write(fn_vol);
1171  LOG("After WRITING vol");
1172 
1173  }
1174  if (verbose)
1175  std::cout << " -----------------------------------------------------------------" << std::endl;
1176  }
1177 }
1178 
1179 // Convergence check ===============================================================
1181 {
1182  LOG_FUNCTION();
1183 
1184  Image<double> vol, old_vol, diff_vol;
1185  FileName fn_base, fn_base_old, fn_vol;
1186  Mask mask_prm;
1187  MultidimArray<int> mask3D;
1188  double signal, change;
1189  int dim;
1190  bool converged = true;
1191 
1192  if (iter == 0)
1193  return false;
1194 
1195  if (verbose)
1196  std::cout << "--> Checking convergence " << std::endl;
1197 
1198  fn_base = FN_ITER_BASE(iter);
1199  fn_base_old = FN_ITER_BASE(iter - 1);
1200 
1201  for (size_t volno = 1; volno <= Nvols; ++volno)
1202  {
1203  // Read corresponding volume from disc
1204  COMPOSE_VOL_FN(fn_vol, volno, fn_base);
1205  //fn_vol.compose(volno, fn_base);
1206  //std::cerr << "DEBUG_JM: fn_vol: " << fn_vol << std::endl;
1207  vol.read(fn_vol);
1208  vol().setXmippOrigin();
1209  dim = vol().rowNumber();
1210  old_vol().initZeros(vol());
1211  diff_vol().initZeros(vol());
1212 
1213  // Only consider voxels within the spherical mask
1214  mask_prm.R1 = dim / 2;
1215  mask_prm.type = BINARY_CIRCULAR_MASK;
1216  mask_prm.mode = INNER_MASK;
1217  mask_prm.generate_mask(vol());
1218  //fn_vol.compose(volno, fn_base_old);
1219  COMPOSE_VOL_FN(fn_vol, volno, fn_base_old);
1220  old_vol.read(fn_vol);
1221  //std::cerr << "DEBUG_JM: oldVol: " << fn_vol << std::endl;
1222  diff_vol() = vol() - old_vol();
1223  mask_prm.apply_mask(old_vol(), old_vol());
1224  mask_prm.apply_mask(diff_vol(), diff_vol());
1225  change = diff_vol().sum2();
1226  signal = old_vol().sum2();
1227  //std::cerr << "DEBUG_JM: change: " << change << std::endl;
1228  //std::cerr << "DEBUG_JM: signal: " << signal << std::endl;
1229  if (change / signal > eps)
1230  converged = false;
1231  if (verbose)
1232  std::cout << formatString("--> Relative signal change volume %d = %f", volno, change / signal) << std::endl;
1233  }
1234 
1235  return converged;
1236 
1237 }
int defaultNiter
Definition: ml2d.h:241
#define dAi(v, i)
void getImageSizeFromFilename(const FileName &filename, size_t &Xdim, size_t &Ydim, size_t &Zdim, size_t &Ndim, MDLabel image_label)
void show() const
Show.
int refs_per_class
Definition: ml2d.h:217
Rotation angle of an image (double,degrees)
void setSampling(double sampling)
Definition: sampling.cpp:121
Definition: ml2d.h:76
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)
virtual void maximization()=0
Update all model parameters, adapted for IEM blocks use.
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
virtual size_t addObject()=0
double getDoubleParam(const char *param, int arg=0)
virtual void read(int argc, const char **argv, bool reportErrors=true)
FileName fn_ref
Definition: ml_refine3d.h:54
void read(const FileName &inFile, const std::vector< MDLabel > *desiredLabels=nullptr, bool decomposeStack=true) override
virtual void clear()
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
FileName replaceExtension(const String &newExt) const
void run()
Provides implementation of the run function.
double tilt_rangeF
Definition: ml_refine3d.h:70
doublereal * c
virtual void produceSideInfo()
virtual void produceSideInfo()=0
Try to merge produceSideInfo1 and 2.
virtual void show() const
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
Definition: mask.h:360
void sqrt(Image< double > &op)
bool getValue(MDObject &mdValueOut, size_t id) const override
size_t current_block
Definition: ml2d.h:229
#define FN_NOISE_IMG_MD
Definition: mlf_align2d.h:59
virtual void write(const FileName &outFile, WriteModeMetaData mode=MD_OVERWRITE) const =0
ModelML2D model
Definition: ml2d.h:224
Tilting angle of an image (double,degrees)
virtual void destroyThreads()
Exit threads and free memory.
Definition: ml2d.h:294
double threshold_solvent
Definition: ml_refine3d.h:77
#define COMPOSE_VOL_FN(fn, volno, base)
Definition: ml_refine3d.cpp:55
int readSymmetryFile(FileName fn_sym, double accuracy=SYM_ACCURACY)
Definition: symmetries.cpp:33
FileName insertBeforeExtension(const String &str) const
#define EMPTY_VOLUMES
Definition: ml_refine3d.h:41
#define EMPTY_PROJECTIONS
Definition: ml_refine3d.h:40
StringVector reconsOutFnBase
Definition: ml_refine3d.h:103
void initProgress(size_t total, size_t stepBin=60)
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)
virtual void createThreads()
Create working threads.
Definition: ml2d.h:289
bool isSymmetryGroup(FileName fn_sym, int &pgGroup, int &pgOrder)
Definition: symmetries.cpp:601
void getImageSize(const MetaData &md, size_t &Xdim, size_t &Ydim, size_t &Zdim, size_t &Ndim, MDLabel image_label)
bool referenceExclusive
Definition: ml2d.h:239
FileName fn_solv
Definition: ml_refine3d.h:54
void compose(const String &str, const size_t no, const String &ext="")
bool do_prob_solvent
Definition: ml_refine3d.h:79
Special label to be used when gathering MDs in MpiMetadataPrograms.
void initConstant(T val)
void write(const FileName &outFile, WriteModeMetaData mode=MD_OVERWRITE) const
FileName fn_img
Definition: ml2d.h:132
int n_ref
Definition: ml2d.h:83
double psi_step
Definition: ml2d.h:158
String integerToString(int I, int _width, char fill_with)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY3D(V)
void removeRedundantPointsExhaustive(const int symmetry, int sym_order, bool only_half_sphere, double max_ang)
Definition: sampling.cpp:1253
FileName fn_mask
Output mask. If not given it is not written.
bool allowRestart
Definition: ml2d.h:239
bool skip_reconstruction
Definition: ml_refine3d.h:88
virtual IdIteratorProxy< false > ids()
FileName fn_root
Definition: ml2d.h:132
String floatToString(float F, int _width, int _prec)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY1D(v)
StringVector reconsMdFn
Definition: ml_refine3d.h:103
ML2DBaseProgram * ml2d
Definition: ml_refine3d.h:105
virtual void createEmptyFiles(int type)
virtual void defineAdditionalParams(XmippProgram *prog, const char *sectionLine)
Definition: ml2d.cpp:266
double angular
Definition: ml_refine3d.h:64
virtual bool checkConvergence()
Convergency check.
size_t size() const override
#define i
void segment(Image< double > &mask)
Is this image enabled? (int [-1 or 1])
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
#define FN_INITIAL_BASE
Definition: ml_refine3d.cpp:48
void CenterFFT(MultidimArray< T > &v, bool forward)
Definition: xmipp_fft.h:291
String defaultRoot
Definition: ml2d.h:240
bool do_ML3D
Definition: ml2d.h:196
void clear() override
#define FN_NOISE_VOLBASE
Definition: ml_refine3d.cpp:52
FileName replaceSubstring(const String &subOld, const String &subNew) const
int argc
Original command line arguments.
Definition: xmipp_program.h:86
void apply_mask(const MultidimArray< T > &I, MultidimArray< T > &result, T subs_val=0, bool apply_geo=false)
Definition: mask.h:635
#define DIRECT_A1D_ELEM(v, i)
#define FOR_ALL_ELEMENTS_IN_ARRAY3D(V)
void computeSamplingPoints(bool only_half_sphere=true, double max_tilt=180, double min_tilt=0)
Definition: sampling.cpp:155
MultidimArray< double > spectral_signal
Definition: ml2d.h:253
const char * getParam(const char *param, int arg=0)
#define XX(v)
Definition: matrix1d.h:85
viol type
bool setValue(const MDObject &mdValueIn, size_t id)
size_t addObject() override
int in
#define FN_PROJECTIONS
Definition: ml_refine3d.cpp:50
FileName fn_sym
Definition: ml_refine3d.h:54
virtual void defineBasicParams(XmippProgram *prog)
Definition: ml2d.cpp:226
#define FN_ITER_BASE(iter)
Definition: ml_refine3d.cpp:47
void importObjects(const MetaData &md, const std::vector< size_t > &objectsToAdd, bool doClear=true) override
#define SPECIAL_ITER
Definition: ml_align2d.h:51
double R1
Definition: mask.h:413
FileName getIterExtraPath(const FileName &fn_root, int iter, bool makePath)
Definition: ml2d.cpp:305
void readParams()
Read additional arguments for 3D-process from command line.
void progress_bar(long rlen)
void defineParams()
Define the parameters accepted.
Definition: ml_refine3d.cpp:76
void apply_cont_mask(const MultidimArray< double > &mask, const MultidimArray< T > &m_in, MultidimArray< T > &m_out)
Definition: mask.h:881
#define RAISED_COSINE
Error related to numerical calculation.
Definition: xmipp_error.h:179
void createSampling()
Create sampling for projecting volumes.
const char ** argv
Definition: xmipp_program.h:87
void radialAverage(const MultidimArray< double > &VolFourierMag, const MultidimArray< double > &V, MultidimArray< double > &radial_mean)
#define dAkij(V, k, i, j)
int type
Definition: mask.h:402
FileName fn_sel
Definition: ml_refine3d.h:54
int istart
Definition: ml2d.h:145
bool wlsart_no_start
Definition: ml_refine3d.h:75
virtual void calculate3DSSNR(MultidimArray< double > &spectral_signal)
Calculate 3D SSNR according to Unser ea. (2005)
void projectVolume(FourierProjector &projector, Projection &P, int Ydim, int Xdim, double rot, double tilt, double psi, const MultidimArray< double > *ctf)
#define FN_CREF_IMG_MD
Definition: mlf_align2d.h:62
void createEmptyFile(const FileName &filename, int xdim, int ydim, int Zdim, size_t select_img, bool isStack, int mode, int _swapWrite, const MDRowVec *md)
int factor_nref
Definition: ml2d.h:215
int verbose
Verbosity level.
bool contains(const String &str) const
void FourierTransform(const MultidimArray< double > &in, MultidimArray< std::complex< double > > &out)
Definition: xmipp_fft.cpp:124
MetaDataDb MDref
Definition: ml2d.h:172
#define STR_EQUAL(str1, str2)
Definition: xmipp_strings.h:42
#define RECONS_ART
Definition: ml_refine3d.h:37
virtual void run()
void initZeros()
Definition: matrix1d.h:592
#define FN_ITER_VOLMD()
Definition: ml_refine3d.h:43
virtual void defineHiddenParams(XmippProgram *prog)
Definition: ml2d.cpp:290
FileName fn_root
Definition: ml_refine3d.h:54
#define j
3D Class to which the image belongs (int)
double tilt_range0
Definition: ml_refine3d.h:70
#define YY(v)
Definition: matrix1d.h:93
#define CLOSE_LOG()
#define LOG_LEVEL(msg)
Definition: xmipp_log.h:89
virtual void projectVolumes(MetaData &mdProj)
Sampling mysampling
Definition: ml_refine3d.h:92
virtual void reconstructVolumes()
reconstruction by (weighted ART) or Fourier interpolation
bool getValue(MDObject &mdValueOut, size_t id) const override
FileName fn_vol
Input volume.
bool setValue(const MDLabel label, const T &valueIn, size_t id)
bool allowFastOption
Definition: ml2d.h:239
#define LOG(msg)
virtual void produceSideInfo2()
std::vector< Matrix1D< double > > no_redundant_sampling_points_angles
Definition: sampling.h:121
void setProgress(size_t value=0)
void dilate3D(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count, int size)
Definition: morphology.cpp:394
void generate_mask(bool apply_geo=false)
Definition: mask.cpp:1577
MetaDataVec mdVol
Definition: ml_refine3d.h:56
#define LOG_FUNCTION()
Definition: xmipp_log.h:90
bool allowIEM
Definition: ml2d.h:239
std::vector< Image< double > > Iref
Definition: ml2d.h:85
FileName fn_ref
Definition: ml2d.h:132
#define BINARY_CIRCULAR_MASK
Definition: mask.h:365
std::string String
Definition: xmipp_strings.h:34
double psi(const double x)
#define SUM_INIT(var, value)
Definition: xmipp_macros.h:458
bool do_deblob_solvent
Definition: ml_refine3d.h:82
FileName fn_symmask
Definition: ml_refine3d.h:54
#define CREATE_LOG()
void show()
Show.
String formatString(const char *format,...)
virtual void copyVolumes()
String outRefsMd
Definition: ml2d.h:250
virtual void postProcessVolumes()
Masking, filtering etc. of the volume.
bool do_mirror
Definition: ml2d.h:137
bool checkParam(const char *param)
#define FN_NOISE_IMG
Definition: mlf_align2d.h:60
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false, int mode=WRITE_READONLY)
#define RECONS_FOURIER
Definition: ml_refine3d.h:38
virtual void expectation()=0
Integrate over all experimental images.
#define FN_PROJECTIONS_MD
Definition: ml_refine3d.cpp:49
virtual void produceSideInfo2()=0
Try to merge produceSideInfo1 and 2.
int idum
void addUsageLine(const char *line, bool verbatim=false)
void initZeros(const MultidimArray< T1 > &op)
Definition: ml2d.h:76
int labelImage3D(const MultidimArray< double > &V, MultidimArray< double > &label)
Definition: filters.cpp:669
void RaisedCosineMask(MultidimArray< double > &mask, double r1, double r2, int mode, double x0, double y0, double z0)
Definition: mask.cpp:36
int getIntParam(const char *param, int arg=0)
virtual ProgReconsBase * createReconsProgram(FileName &input, FileName &output)
Create the program to be used for reconstruction of the volumes.
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false)
void FFT_magnitude(const MultidimArray< std::complex< double > > &v, MultidimArray< double > &mag)
Definition: xmipp_fftw.cpp:393
std::vector< Image< double > > Iold
Definition: ml2d.h:176
Incorrect value received.
Definition: xmipp_error.h:195
size_t blocks
Definition: ml2d.h:227
Name of an image (std::string)
int threads
Definition: ml2d.h:244
double lowpass
Definition: ml_refine3d.h:68
SymList SL
Definition: sampling.h:138
virtual void endIteration()
Do some task at the end of iteration.
Definition: ml2d.cpp:168
void clear()
Definition: xmipp_image.h:144
#define LOWPASS
void addParamsLine(const String &line)
int mode
Definition: mask.h:407
void applyMaskSpace(MultidimArray< double > &v)
#define FN_CREF_VOLBASE
Definition: ml_refine3d.cpp:53
< Score 4 for volumes
void updateVolumesMetadata()
ProgMLRefine3D(bool fourier=false)
Definition: ml_refine3d.cpp:58
virtual void writeOutputFiles(const ModelML2D &model, OutputType outputType=OUT_FINAL)=0
Write output files.
constexpr int INNER_MASK
Definition: mask.h:47
virtual void makeNoiseImages()
(For mpi-version only:) calculate noise averages and write to disc
bool do_prob
From here on by Sjors.