void getFSC(MultidimArray< double >& m1, MultidimArray< double >& m2, MultidimArray< double >& fsc) { MultidimArray< Complex > FT1, FT2; FourierTransformer transformer; transformer.FourierTransform(m1, FT1); transformer.FourierTransform(m2, FT2); getFSC(FT1, FT2, fsc); }
void Postprocessing::run() { // Read inout maps and perform some checks initialise(); // Calculate FSC of the unmask maps getFSC(I1(), I2(), fsc_unmasked); // Check whether we'll do masking do_mask = getMask(); if (do_mask) { if (verb > 0) { std::cout <<"== Masking input maps ..." <<std::endl; } // Mask I1 and I2 and calculated fsc_masked I1() *= Im(); I2() *= Im(); getFSC(I1(), I2(), fsc_masked); // To save memory re-read the same input maps again and randomize phases before masking I1.read(fn_I1); I2.read(fn_I2); I1().setXmippOrigin(); I2().setXmippOrigin(); // Check at which resolution shell the FSC drops below randomize_fsc_at int randomize_at = -1; FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY1D(fsc_unmasked) { if (i > 0 && DIRECT_A1D_ELEM(fsc_unmasked, i) < randomize_fsc_at) { randomize_at = i; break; } } if (verb > 0) { std::cout.width(35); std::cout << std::left << " + randomize phases beyond: "; std::cout << XSIZE(I1())* angpix / randomize_at << " Angstroms" << std::endl; } if (randomize_at > 0) { randomizePhasesBeyond(I1(), randomize_at); randomizePhasesBeyond(I2(), randomize_at); // Mask randomized phases maps and calculated fsc_random_masked I1() *= Im(); I2() *= Im(); getFSC(I1(), I2(), fsc_random_masked); } else REPORT_ERROR("Postprocessing::run ERROR: FSC curve never drops below randomize_fsc_at. You may want to check your mask."); // Now that we have fsc_masked and fsc_random_masked, calculate fsc_true according to Richard's formula // FSC_true = FSC_t - FSC_n / ( ) fsc_true.resize(fsc_masked); FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY1D(fsc_true) { // 29jan2015: let's move this 2 shells upwards, because of small artefacts near the resolution of randomisation! if (i < randomize_at + 2) { DIRECT_A1D_ELEM(fsc_true, i) = DIRECT_A1D_ELEM(fsc_masked, i); } else { DOUBLE fsct = DIRECT_A1D_ELEM(fsc_masked, i); DOUBLE fscn = DIRECT_A1D_ELEM(fsc_random_masked, i); if (fscn > fsct) DIRECT_A1D_ELEM(fsc_true, i) = 0.; else DIRECT_A1D_ELEM(fsc_true, i) = (fsct - fscn) / (1. - fscn); } } // Now re-read the original maps yet again into memory I1.read(fn_I1); I2.read(fn_I2); I1().setXmippOrigin(); I2().setXmippOrigin(); } else {