56 addUsageLine(
"This function determines the local resolution of a tomogram. It makes use of two reconstructions, odd and even. The difference between them" 57 "gives a noise reconstruction. Thus, by computing the local amplitude of the signal at different frequencies and establishing a comparison with" 58 "the noise, the local resolution is computed");
61 addParamsLine(
" -o <output=\"MGresolution.vol\"> : Local resolution volume (in Angstroms)");
62 addParamsLine(
" --meanVol <vol_file=\"\"> : Mean volume of half1 and half2 (only it is necessary the two haves are used)");
63 addParamsLine(
" [--sampling_rate <s=1>] : Sampling rate (A/px)");
64 addParamsLine(
" [--step <s=0.25>] : The resolution is computed at a number of frequencies between minimum and");
65 addParamsLine(
" : maximum resolution px/A. This parameter determines that number");
68 addParamsLine(
" [--significance <s=0.95>] : The level of confidence for the hypothesis test.");
75 std::cout <<
"Starting..." << std::endl;
76 std::cout <<
" " << std::endl;
77 std::cout <<
"IMPORTANT: If the angular step of the tilt series is higher than 3 degrees"<< std::endl;
78 std::cout <<
" then, the tomogram is not properly for MonoTomo. Despite this is not "<< std::endl;
79 std::cout <<
" optimal, MonoTomo will try to compute the local resolution." << std::endl;
80 std::cout <<
" " << std::endl;
87 auto &tomo = signalTomo();
88 auto &noise = noiseTomo();
95 tomo.setXmippOrigin();
96 noise.setXmippOrigin();
98 mask().resizeNoCopy(tomo);
99 mask().initConstant(1);
112 const auto fftSettingBackward = fftSettingForward.createInverse();
118 backward_transformer->init(hw, fftSettingBackward);
120 const auto &fdim = fftSettingForward.fDim();
141 int N_smoothing = 10;
143 int siz_z = zdim*0.5;
144 int siz_y =
ydim*0.5;
145 int siz_x =
xdim*0.5;
148 int limit_distance_x = (siz_x-N_smoothing);
149 int limit_distance_y = (siz_y-N_smoothing);
150 int limit_distance_z = (siz_z-N_smoothing);
155 auto uz = (
k - siz_z);
158 auto uy = (
i - siz_y);
161 auto ux = (
j - siz_x);
163 if (
abs(ux)>=limit_distance_x)
168 if (
abs(uy)>=limit_distance_y)
173 if (
abs(uz)>=limit_distance_z)
190 std::complex<float> J(0,1);
194 float ideltal=
PI/(freq-freqH);
205 auto uy2uz2 = uz2 +uy*uy;
213 if (freqH<=u && u<=freq)
215 fftVRiesz[
n] = myfftV[
n]*0.5f*(1+std::cos((u-freq)*ideltal));
285 fftVRiesz_aux[
n] = uz*fftVRiesz_aux[
n];
308 float raised_w =
PI/(freqL-freq);
322 auto uy2uz2 = uz2 +uy*uy;
336 if (freqL>=
u &&
u>=freq)
338 fftVRiesz[
n] *= 0.5f*(1 + std::cos(raised_w*(
u-freq)));
358 int Nx = xdim/boxsize;
359 int Ny = ydim/boxsize;
370 double hX = xdim / (double)(lX-3);
371 double hY = ydim / (double)(lY-3);
373 if ( (xdim<boxsize) || (ydim<boxsize) )
374 std::cout <<
"Error: The tomogram in x-direction or y-direction is too small" << std::endl;
376 std::vector<double> noiseVector(1);
377 std::vector<double>
x,
y,t;
379 int xLimit, yLimit, xStart, yStart;
384 for (
int X_boxIdx=0; X_boxIdx<Nx; ++X_boxIdx)
388 xStart =
STARTINGX(noiseMap) + X_boxIdx*boxsize;
393 xStart =
STARTINGX(noiseMap) + X_boxIdx*boxsize;
394 xLimit =
STARTINGX(noiseMap) + (X_boxIdx+1)*boxsize;
397 for (
int Y_boxIdx=0; Y_boxIdx<Ny; ++Y_boxIdx)
401 yStart =
STARTINGY(noiseMap) + Y_boxIdx*boxsize;
406 yStart =
STARTINGY(noiseMap) + Y_boxIdx*boxsize;
407 yLimit =
STARTINGY(noiseMap) + (Y_boxIdx+1)*boxsize;
413 for (
int i = yStart;
i<yLimit;
i++)
415 for (
int j = xStart;
j<xLimit;
j++)
419 if (counter%257 == 0)
420 noiseVector.push_back(
A3D_ELEM(noiseMap,
k,
i,
j) );
426 std::sort(noiseVector.begin(),noiseVector.end());
429 MAT_ELEM(noiseMatrix, Y_boxIdx, X_boxIdx) = noiseVector[size_t(noiseVector.size()*
significance)];
431 double tileCenterY=0.5*(yLimit+yStart)-
STARTINGY(noiseMap);
432 double tileCenterX=0.5*(xLimit+xStart)-
STARTINGX(noiseMap);
435 for(
int controlIdxY = -1; controlIdxY < (lY - 1); ++controlIdxY)
437 double tmpY =
Bspline03((tileCenterY / hY) - controlIdxY);
445 for(
int controlIdxX = -1; controlIdxX < (lX - 1); ++controlIdxX)
447 double tmpX =
Bspline03((tileCenterX / hX) - controlIdxX);
448 MAT_ELEM(helper.
A,idxBox,idxSpline) = tmpY * tmpX;
452 x.push_back(tileCenterX);
453 y.push_back(tileCenterY);
454 t.push_back(
MAT_ELEM(noiseMatrix, Y_boxIdx, X_boxIdx));
473 for(
int controlIdxY = -1; controlIdxY < (lY - 1); ++controlIdxY)
475 double tmpY =
Bspline03((
i / hY) - controlIdxY);
484 for(
int controlIdxX = -1; controlIdxX < (lX - 1); ++controlIdxX)
486 double tmpX =
Bspline03((
j / hX) - controlIdxX);
487 xContrib+=
VEC_ELEM(cij,idxSpline) * tmpX;
500 std::vector<float> &list)
503 float init_res, last_res;
506 last_res = list[(list.size()-1)];
508 auto last_resolution_2 = list[last_res];
511 lowest_res = list[1];
515 std::vector<float> resolVec(0);
520 if ( (rVol>=(last_resolution_2-0.001)) && (rVol<=lowest_res) )
522 resolVec.push_back(rVol);
528 std::sort(resolVec.begin(), resolVec.end());
530 std::cout <<
"median Resolution = " << resolVec[(int)(0.5*N)] << std::endl;
536 std::vector<float> &list,
float &cut_value,
float &resolutionThreshold)
538 double last_resolution_2 = list[(list.size()-1)];
541 lowest_res = list[0];
546 std::vector<double> resolVec(0);
550 if (rVol>=(last_resolution_2-0.001))
552 resolVec.push_back(rVol);
559 std::sort(resolVec.begin(), resolVec.end());
561 resolutionThreshold = resolVec[(int)((0.95)*N)];
563 std::cout <<
"resolutionThreshold = " << resolutionThreshold << std::endl;
569 float isigma2 = (sigma*sigma);
585 double uy2uz2 = uz2 +uy*uy;
591 const float u2 = (float) (uy2uz2 + ux*ux);
623 float resolution, last_resolution = 10000;
624 double freq, freqH, freqL;
625 double max_meanS = -1e38;
626 float cut_value = 0.025;
633 bool doNextIteration=
true;
635 bool lefttrimming =
false;
636 int last_fourier_idx = -1;
642 std::vector<float> list;
644 std::cout <<
"Analyzing frequencies" << std::endl;
645 std::cout <<
" " << std::endl;
646 std::vector<float> noiseValues;
647 float lastResolution = 1e38;
651 for (
size_t idx = 0; idx<maxIdx; idx++)
655 if (candidateResolution<=
minRes)
661 freq =
sampling/candidateResolution;
670 if (lastResolution-resolution<resStep)
675 lastResolution = resolution;
680 int fourier_idx_freqL;
683 if (fourier_idx_freqL == fourier_idx)
685 if (fourier_idx > 0){
693 list.push_back(resolution);
698 resolution_2 = list[iter - 2];
711 localNoise(amplitudeMN, noiseMatrix, boxsize, thresholdMatrix);
714 float sumS=0, sumS2=0, sumN=0, sumN2=0, NN = 0, NS = 0;
723 sumS += amplitudeValue;
724 noiseValues.push_back(amplitudeValueN);
725 sumN += amplitudeValueN;
733 std::cout <<
"There are no points to compute inside the mask" << std::endl;
734 std::cout <<
"If the number of computed frequencies is low, perhaps the provided" 735 "mask is not enough tight to the volume, in that case please try another mask" << std::endl;
739 double meanS=sumS/NS;
744 if (meanS<0.001*max_meanS)
746 std::cout <<
"Search of resolutions stopped due to too low signal" << std::endl;
750 std::cout <<
"resolution = " << resolution <<
" resolution_2 = " << resolution_2 << std::endl;
778 outputResolutionImage2() = outputResolution;
779 outputResolutionImage2.
write(
"local.mrc");
787 float resolutionThreshold;
796 if ( (value<resolutionThreshold) && (value>resVal) )
810 if ( (value<resolutionThreshold) && (value>resVal) )
820 outputResolutionImage2() =
VRiesz;
void min(Image< double > &op1, const Image< double > &op2)
void lowestResolutionbyPercentile(MultidimArray< double > &resolutionVol, std::vector< double > &list, double &cut_value, double &resolutionThreshold)
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
double getDoubleParam(const char *param, int arg=0)
std::unique_ptr< AFT< float > > forward_transformer
void localNoise(MultidimArray< double > &noiseMap, Matrix2D< double > &noiseMatrix, int boxsize, Matrix2D< double > &thresholdMatrix)
void resizeNoCopy(const MultidimArray< T1 > &v)
void sqrt(Image< double > &op)
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)
MultidimArray< double > VRiesz
double icdf_gauss(double p)
#define MULTIDIM_ARRAY(v)
void abs(Image< double > &op)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY3D(V)
#define DIGFREQ2FFT_IDX(freq, size, idx)
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 MAT_ELEM(m, i, j)
#define A3D_ELEM(V, k, i, j)
const char * getParam(const char *param, int arg=0)
void smoothBorders(MultidimArray< float > &vol, MultidimArray< int > &pMask)
double Bspline03(double Argument)
void max(Image< double > &op1, const Image< double > &op2)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define DIRECT_MULTIDIM_ELEM(v, n)
std::vector< std::complex< float > > fourierSignal
std::unique_ptr< AFT< float > > backward_transformer
void sort(struct DCEL_T *dcel)
#define DIRECT_A3D_ELEM(v, k, i, j)
void amplitudeMonogenicSignal3D(MultidimArray< std::complex< double > > &myfftV, double freq, double freqH, double freqL, MultidimArray< double > &litude, int count, FileName fnDebug)
__device__ float FFT_IDX2DIGFREQ(int idx, int size)
MultidimArray< std::complex< double > > fftVRiesz
std::vector< std::complex< float > > fourierNoise
String formatString(const char *format,...)
MultidimArray< std::complex< double > > fftVRiesz_aux
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false, int mode=WRITE_READONLY)
void gaussFilter(const MultidimArray< float > &vol, const float, MultidimArray< float > &VRiesz)
void addUsageLine(const char *line, bool verbatim=false)
void initZeros(const MultidimArray< T1 > &op)
void weightedLeastSquares(WeightedLeastSquaresHelper &h, Matrix1D< double > &result)
int getIntParam(const char *param, int arg=0)
void addParamsLine(const String &line)
void postProcessingLocalResolutions(MultidimArray< double > &resolutionVol, std::vector< double > &list)