void Postprocessing::makeGuinierPlot(MultidimArray<Complex > &FT, std::vector<fit_point2D> &guinier) { MultidimArray<int> radial_count(XSIZE(FT)); MultidimArray<DOUBLE> lnF(XSIZE(FT)); fit_point2D onepoint; FOR_ALL_ELEMENTS_IN_FFTW_TRANSFORM(FT) { int r2 = kp * kp + ip * ip + jp * jp; int ires = ROUND(sqrt((DOUBLE)r2)); if (ires < XSIZE(radial_count)) { lnF(ires) += abs(DIRECT_A3D_ELEM(FT, k, i, j)); radial_count(ires)++; } } DOUBLE xsize = XSIZE(I1()); guinier.clear(); FOR_ALL_ELEMENTS_IN_ARRAY1D(radial_count) { DOUBLE res = (xsize * angpix)/(DOUBLE)i; // resolution in Angstrom if (res >= angpix * 2.) // Apply B-factor sharpening until Nyquist, then low-pass filter later on (with a soft edge) { onepoint.x = 1. / (res * res); if (DIRECT_A1D_ELEM(lnF, i) > 0.) { onepoint.y = log ( DIRECT_A1D_ELEM(lnF, i) / DIRECT_A1D_ELEM(radial_count, i) ); if (res <= fit_minres && res >= fit_maxres) { onepoint.w = 1.; } else { onepoint.w = 0.; } } else { onepoint.y = -99.; onepoint.w = 0.; } //std::cerr << " onepoint.x= " << onepoint.x << " onepoint.y= " << onepoint.y << " onepoint.w= " << onepoint.w << std::endl; guinier.push_back(onepoint); } } }
// Fourier ring correlation ----------------------------------------------- // from precalculated Fourier Transforms, and without sampling rate etc. void getFSC(MultidimArray< Complex >& FT1, MultidimArray< Complex >& FT2, MultidimArray< double >& fsc) { if (!FT1.sameShape(FT2)) { REPORT_ERROR("fourierShellCorrelation ERROR: MultidimArrays have different shapes!"); } MultidimArray< int > radial_count(XSIZE(FT1)); MultidimArray<double> num, den1, den2; Matrix1D<double> f(3); num.initZeros(radial_count); den1.initZeros(radial_count); den2.initZeros(radial_count); fsc.initZeros(radial_count); FOR_ALL_ELEMENTS_IN_FFTW_TRANSFORM(FT1) { int idx = ROUND(sqrt(kp * kp + ip * ip + jp * jp)); if (idx >= XSIZE(FT1)) { continue; } Complex z1 = DIRECT_A3D_ELEM(FT1, k, i, j); Complex z2 = DIRECT_A3D_ELEM(FT2, k, i, j); double absz1 = abs(z1); double absz2 = abs(z2); num(idx) += (conj(z1) * z2).real; den1(idx) += absz1 * absz1; den2(idx) += absz2 * absz2; radial_count(idx)++; } FOR_ALL_ELEMENTS_IN_ARRAY1D(fsc) { fsc(i) = num(i) / sqrt(den1(i) * den2(i)); } }