99 static bool randomized =
false;
103 std::mt19937
g(
seed);
123 std::cerr<<
">>>>>>>> entering checkConvergence"<<std::endl;
129 bool converged =
true;
138 for (
int refno = 0; refno <
model.
n_ref; refno++)
144 Maux =
Iold[refno]() *
Iold[refno]();
156 conv.push_back(convv);
160 std::cerr<<
"<<<<<< leaving checkConvergence"<<std::endl;
178 bool converged =
false;
181 LOG(
" starting produceSideInfo\n");
185 LOG(
" starting produceSideInfo2\n");
189 LOG(
" createThreads\n");
192 LOG(
" starting iterations\n");
197 std::cout <<
" Multi-reference refinement: iteration " << iter <<
" of " <<
Niter << std::endl;
199 for (
int refno = 0;refno <
model.
n_ref; refno++)
215 std::cout << (converged ?
216 "--> Optimization converged!" :
217 "--> Optimization was stopped before convergence was reached!")
228 prog->
addParamsLine(
" -i <input_file> : Metadata or stack with input images ");
230 String orStr =
"", lb =
"", rb =
"";
237 prog->
addParamsLine(
" [ --nref <int=1> ] : Number of references to generate automatically (recommended)");
238 prog->
addParamsLine(
" [ --ref <reference_file=\"\"> ] : Image, stack or metadata with initial(s) references(s)");
241 prog->
addParamsLine(
" [ --mirror ] : Also check mirror image of each reference ");
245 prog->
addParamsLine(
" [ --fast ] : Use pre-centered images to pre-calculate significant orientations.");
246 prog->
addParamsLine(
":++ If this flag is set part of the integration over all references, rotations and translations is skipped.");
247 prog->
addParamsLine(
":++ The program will store all (=N_imgs*N_refs=) origin offsets that yield the maximum probability of observing");
248 prog->
addParamsLine(
":++ each experimental image, given each of the references. In the first iterations a complete integration over");
249 prog->
addParamsLine(
":++ all references, rotations and translations is performed for all images. In all subsequent iterations, for all");
250 prog->
addParamsLine(
":++ combinations of experimental images, references and rotations, the probability of observing the image given");
251 prog->
addParamsLine(
":++ the optimal origin offsets from the previous iteration is calculated. Then, if this probability is not");
252 prog->
addParamsLine(
":++ considered \"significant\", we assume that none of the other translations will be significant, and we skip");
253 prog->
addParamsLine(
":++ the integration over the translations. A combination of experimental image, reference and rotation is considered");
254 prog->
addParamsLine(
":++ as \"significant\" if the probability at the corresponding optimal origin offsets is larger than C times the");
255 prog->
addParamsLine(
":++ maximum of all these probabilities for that experimental image and reference (by default C=1e-12) This version");
256 prog->
addParamsLine(
":++ may run up to ten times faster than the original, complete-search approach, while practically identical results may be obtained.");
260 prog->
addParamsLine(
" [ --thr <N=1> ] : Use N parallel threads ");
262 prog->
addParamsLine(
" [ --iem <blocks=1>] : Number of blocks to be used with IEM");
269 prog->
addParamsLine(
" [ --eps <float=5e-5> ] : Stopping criterium");
271 prog->
addParamsLine(
" [ --psi_step <float=5.> ] : In-plane rotation sampling interval [deg]");
272 prog->
addParamsLine(
" [ --noise <float=1> ] : Expected standard deviation for pixel noise ");
273 prog->
addParamsLine(
" [ --offset <float=3.> ] : Expected standard deviation for origin offset [pix]");
274 prog->
addParamsLine(
" [ --frac <docfile=\"\"> ] : Docfile with expected model fractions (default: even distr.)");
275 prog->
addParamsLine(
" [ -C <double=1e-12> ] : Significance criterion for fast approach ");
276 prog->
addParamsLine(
" [ --zero_offsets ] : Kick-start the fast algorithm from all-zero offsets ");
278 prog->
addParamsLine(
" [ --restart <iter=1> ] : restart a run with all parameters as in the logfile ");
279 prog->
addParamsLine(
" [ --fix_sigma_noise ] : Do not re-estimate the standard deviation in the pixel noise ");
280 prog->
addParamsLine(
" [ --fix_sigma_offset ] : Do not re-estimate the standard deviation in the origin offsets ");
281 prog->
addParamsLine(
" [ --fix_fractions ] : Do not re-estimate the model fractions ");
282 prog->
addParamsLine(
" [ --student <df=6>] : Use t-distributed instead of Gaussian model for the noise ");
283 prog->
addParamsLine(
" : df = Degrees of freedom for the t-distribution ");
284 prog->
addParamsLine(
" [ --norm ] : Refined normalization parameters for each particle ");
285 prog->
addParamsLine(
" [ --save_memA ] : Save memory A(deprecated)");
286 prog->
addParamsLine(
" [ --save_memB ] : Save memory B(deprecated)");
331 sumw_allrefs2 = sumw_allrefs = 0.;
333 do_student_sigma_trick =
true;
334 sigma_noise = sigma_offset = LL = avePmax = 0.;
335 wsum_sigma_noise = wsum_sigma_offset = 0.;
345 Iempty().initZeros(
dim,
dim);
346 Iempty().setXmippOrigin();
348 Iref.resize(n_ref, Iempty);
349 WsumMref.resize(n_ref, Iempty);
350 alpha_k.resize(n_ref, 0.);
351 mirror_fraction.resize(n_ref, 0.);
352 scale.resize(n_ref, 1.);
353 sumw_mirror.resize(n_ref, 0.);
354 sumwsc.resize(n_ref, 0.);
362 if (n_ref != model.
n_ref)
365 #define COMBINE(var) var += sign * model.var 374 double sumweight = 0., w1 = 0., w2 = 0.;
376 for (
int refno = 0; refno < n_ref; refno++)
378 w1 = WsumMref[refno].weight();
379 w2 = sign * model.
WsumMref[refno].weight();
382 WsumMref[refno]() += tmp;
387 Iref[refno].setWeight(sumweight);
388 WsumMref[refno].setWeight(sumweight);
394 Iref[refno]().initZeros();
395 WsumMref[refno]().initZeros();
396 Iref[refno].setWeight(0);
397 WsumMref[refno].setWeight(0.);
398 sumw_mirror[refno] = 0.;
406 combineModel(model, 1);
411 combineModel(model, -1);
416 if (sumw_allrefs < 0)
420 double sum = (do_student && do_student_sigma_trick) ? sumw_allrefs2
422 double sigma_noise2 = wsum_sigma_noise / (sum *
dim *
dim);
424 if (sigma_noise2 < 0.)
426 sigma_noise =
sqrt(sigma_noise2);
429 if (wsum_sigma_offset < 0.)
431 sigma_offset =
sqrt(wsum_sigma_offset / (2. * sumw_allrefs));
434 avePmax = sumfracweight / sumw_allrefs;
436 double weight, inv_weight;
440 for (
int refno = 0; refno < n_ref; ++refno)
442 weight = WsumMref[refno].weight();
449 Iref[refno].setWeight(weight);
450 inv_weight = 1 / weight;
451 Iref[refno]() = WsumMref[refno]();
452 Iref[refno]() *= inv_weight;
454 alpha_k[refno] = weight / sumw_allrefs;
455 mirror_fraction[refno] = sumw_mirror[refno] * inv_weight;
456 scale[refno] = sumwsc[refno] * inv_weight;
464 Iref[refno].setWeight(0.);
465 Iref[refno]().initZeros(WsumMref[refno]());
467 mirror_fraction[refno] = 0.;
473 #define pp(s, x) s << std::setw(10) << x 478 for (
int t = 0; t < tabs; ++t)
481 std::cerr <<
"======================= Block ==================== " << std::endl;
483 std::cerr <<
"sumw_allrefs: " << sumw_allrefs << std::endl;
484 std::cerr <<
"wsum_sigma_offset: " << wsum_sigma_offset << std::endl;
485 std::cerr <<
"wsum_sigma_noise: " << wsum_sigma_noise << std::endl;
486 std::cerr <<
"sigma_offset: " << sigma_offset << std::endl;
487 std::cerr <<
"sigma_noise: " << sigma_noise << std::endl;
488 std::cerr <<
"LL: " << LL << std::endl;
490 std::stringstream ss1, ss2, ss3, ss4, ss5, ss6, ss7;
492 pp(ss3,
"sumw_mirror:");
494 pp(ss5,
"mirror_fraction");
495 pp(ss6,
"WsumMref.weight");
496 pp(ss7,
"Iref.weight");
498 for (
int refno = 0; refno < n_ref; refno++)
501 pp(ss3, sumw_mirror[refno]);
502 pp(ss4, alpha_k[refno]);
503 pp(ss5, mirror_fraction[refno]);
504 pp(ss6, WsumMref[refno].weight());
505 pp(ss7, Iref[refno].weight());
507 std::cerr << ss1.str() << std::endl<< ss3.str() << std::endl
508 << ss4.str() << std::endl<< ss5.str() << std::endl << ss6.str() << std::endl << ss7.str()<< std::endl;
std::vector< size_t > img_id
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
#define REPORT_ERROR(nerr, ErrormMsg)
virtual void produceSideInfo()=0
Try to merge produceSideInfo1 and 2.
void sqrt(Image< double > &op)
virtual void destroyThreads()
Exit threads and free memory.
virtual void createThreads()
Create working threads.
void substractModel(const ModelML2D &model)
virtual void iteration()=0
virtual void defineAdditionalParams(XmippProgram *prog, const char *sectionLine)
bool do_norm
Re-normalize internally.
void print(int tabs=0) const
Just for debugging now.
virtual void run()
Main function of the program.
void combineModel(const ModelML2D &model, int sign)
virtual void defineBasicParams(XmippProgram *prog)
std::vector< Matrix2D< double > > F
FileName getIterExtraPath(const FileName &fn_root, int iter, bool makePath)
MultidimArray< double > docfiledata
int makePath(mode_t mode=0755) const
int verbose
Verbosity level.
virtual void defineHiddenParams(XmippProgram *prog)
virtual void addPartialDocfileData(const MultidimArray< double > &data, size_t first, size_t last)=0
Add docfiledata to docfile.
virtual void setNumberOfLocalImages()
Set the number of images, this function is useful only for MPI.
std::vector< Image< double > > Iref
String formatString(const char *format,...)
virtual bool checkConvergence()
virtual void randomizeImagesOrder()
Randomize initial images order, only once.
virtual void produceSideInfo2()=0
Try to merge produceSideInfo1 and 2.
double computeAvg() const
std::vector< Image< double > > WsumMref
Incorrect value received.
std::vector< Image< double > > Iold
std::vector< double > conv
virtual void endIteration()
Do some task at the end of iteration.
void addParamsLine(const String &line)
void addModel(const ModelML2D &model)
virtual void writeOutputFiles(const ModelML2D &model, OutputType outputType=OUT_FINAL)=0
Write output files.