Xmipp  v3.23.11-Nereus
resolution_monotomo.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Jose Luis Vilas, jlvilas@cnb.csic.es
4  * Oier Lauzirika olauzirika@cnb.csic.es
5  * Carlos Oscar S. Sorzano coss@cnb.csic.es (2019)
6  *
7  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22  * 02111-1307 USA
23  *
24  * All comments concerning this program package may be sent to the
25  * e-mail address 'xmipp@cnb.csic.es'
26  ***************************************************************************/
27 
28 #include "resolution_monotomo.h"
29 
30 #include <core/bilib/kernel.h>
32 #include "data/fftwT.h"
33 #include <cmath>
34 
35 #include <data/aft.h>
36 #include <data/fft_settings.h>
37 #include <cmath>
38 
40 {
41  fnVol = getParam("--vol");
42  fnVol2 = getParam("--vol2");
43  fnMeanVol = getParam("--meanVol");
44  fnOut = getParam("-o");
45  sampling = getDoubleParam("--sampling_rate");
46  minRes = getDoubleParam("--minRes");
47  maxRes = getDoubleParam("--maxRes");
48  resStep = getDoubleParam("--step");
49  significance = getDoubleParam("--significance");
50  nthrs = getIntParam("--threads");
51 }
52 
53 
55 {
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");
59  addParamsLine(" --vol <vol_file=\"\"> : Half volume 1");
60  addParamsLine(" --vol2 <vol_file=\"\"> : Half volume 2");
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");
66  addParamsLine(" [--minRes <s=30>] : Minimum resolution (A)");
67  addParamsLine(" [--maxRes <s=1>] : Maximum resolution (A)");
68  addParamsLine(" [--significance <s=0.95>] : The level of confidence for the hypothesis test.");
69  addParamsLine(" [--threads <s=4>] : Number of threads");
70 }
71 
72 
74 {
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;
81 
82  Image<float> signalTomo;
83  Image<float> noiseTomo;
84  signalTomo.read(fnVol);
85  noiseTomo.read(fnVol2);
86 
87  auto &tomo = signalTomo();
88  auto &noise = noiseTomo();
89 
90  // Compute the average and difference
91  tomo += noise;
92  tomo *= 0.5;
93  noise -= tomo;
94 
95  tomo.setXmippOrigin();
96  noise.setXmippOrigin();
97 
98  mask().resizeNoCopy(tomo);
99  mask().initConstant(1);
100 
101  xdim = XSIZE(tomo);
102  ydim = YSIZE(tomo);
103  zdim = ZSIZE(tomo);
104 
105 
106  smoothBorders(tomo, mask());
107  smoothBorders(noise, mask());
108 
109  float normConst = xdim * ydim * zdim;
110 
111  const FFTSettings<float> fftSettingForward(xdim, ydim, zdim);
112  const auto fftSettingBackward = fftSettingForward.createInverse();
113 
114  auto hw = CPU(nthrs);
115  forward_transformer = std::make_unique<FFTwT<float>>();
116  backward_transformer = std::make_unique<FFTwT<float>>();
117  forward_transformer->init(hw, fftSettingForward);
118  backward_transformer->init(hw, fftSettingBackward);
119 
120  const auto &fdim = fftSettingForward.fDim();
121  fourierSignal.resize(fdim.size());
122  fourierNoise.resize(fdim.size());
124  forward_transformer->fft(MULTIDIM_ARRAY(noise), fourierNoise.data());
125 
126  // Clear images in real space as they are not longer needed
127  signalTomo.clear();
128  noiseTomo.clear();
129 
130  xdimFT = fdim.x();
131  ydimFT = fdim.y();
132  zdimFT = fdim.z();
133 
134 
135  VRiesz.resizeNoCopy(1, zdim, ydim, xdim);
136 
137 }
138 
140 {
141  int N_smoothing = 10;
142 
143  int siz_z = zdim*0.5;
144  int siz_y = ydim*0.5;
145  int siz_x = xdim*0.5;
146 
147 
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);
151 
152  long n=0;
153  for(int k=0; k<zdim; ++k)
154  {
155  auto uz = (k - siz_z);
156  for(int i=0; i<ydim; ++i)
157  {
158  auto uy = (i - siz_y);
159  for(int j=0; j<xdim; ++j)
160  {
161  auto ux = (j - siz_x);
162 
163  if (abs(ux)>=limit_distance_x)
164  {
165  DIRECT_MULTIDIM_ELEM(vol, n) *= 0.5*(1+std::cos(PI*(limit_distance_x - std::abs(ux))/N_smoothing));
166  DIRECT_MULTIDIM_ELEM(pMask, n) = 0;
167  }
168  if (abs(uy)>=limit_distance_y)
169  {
170  DIRECT_MULTIDIM_ELEM(vol, n) *= 0.5*(1+std::cos(PI*(limit_distance_y - std::abs(uy))/N_smoothing));
171  DIRECT_MULTIDIM_ELEM(pMask, n) = 0;
172  }
173  if (abs(uz)>=limit_distance_z)
174  {
175  DIRECT_MULTIDIM_ELEM(vol, n) *= 0.5*(1+std::cos(PI*(limit_distance_z - std::abs(uz))/N_smoothing));
176  DIRECT_MULTIDIM_ELEM(pMask, n) = 0;
177  }
178  ++n;
179  }
180  }
181  }
182 }
183 
184 
185 void ProgMonoTomo::amplitudeMonogenicSignal3D(const std::vector<std::complex<float>> &myfftV, float freq, float freqH,
186  float freqL, MultidimArray<float> &amplitude, int count, FileName fnDebug)
187 {
190  std::complex<float> J(0,1);
191 
192  // Filter the input volume and add it to amplitude
193  size_t n=0;
194  float ideltal=PI/(freq-freqH);
195  for(size_t k=0; k<zdimFT; ++k)
196  {
197  double uz;// = VEC_ELEM(freq_fourier_z, k);
198  FFT_IDX2DIGFREQ(k, zdim, uz);
199  auto uz2 = uz*uz;
200  for(size_t i=0; i<ydimFT; ++i)
201  {
202  //const auto uy = VEC_ELEM(freq_fourier_y, i);
203  double uy;
204  FFT_IDX2DIGFREQ(i, ydim, uy);
205  auto uy2uz2 = uz2 +uy*uy;
206  for(size_t j=0; j<xdimFT; ++j)
207  {
208  double ux;
209  FFT_IDX2DIGFREQ(j, xdim, ux);
210  //const auto ux = VEC_ELEM(freq_fourier_x, j);
211  const float u = std::sqrt(uy2uz2 + ux*ux);
212 
213  if (freqH<=u && u<=freq)
214  {
215  fftVRiesz[n] = myfftV[n]*0.5f*(1+std::cos((u-freq)*ideltal));
216  fftVRiesz_aux[n] = -J*fftVRiesz[n]/u;
217  }
218  else
219  {
220  if (u>freq)
221  {
222  fftVRiesz[n] = myfftV[n];
223  fftVRiesz_aux[n] = -J*fftVRiesz[n]/u;
224  }
225  else
226  {
227  fftVRiesz[n] = 0.0f;
228  fftVRiesz_aux[n] = 0.0f;
229  }
230  }
231  n++;
232 
233  }
234  }
235  }
236 
237  backward_transformer->ifft(fftVRiesz.data(), MULTIDIM_ARRAY(VRiesz));
238 
239 
240  amplitude = VRiesz;
241 
243  {
244  DIRECT_MULTIDIM_ELEM(amplitude, n) *= DIRECT_MULTIDIM_ELEM(VRiesz, n);
245  }
246 
247 
248  // Calculate first component of Riesz vector
249  float uz, uy, ux;
250  n=0;
251  for(size_t k=0; k<zdimFT; ++k)
252  {
253  for(size_t i=0; i<ydimFT; ++i)
254  {
255  for(size_t j=0; j<xdimFT; ++j)
256  {
257  //ux = VEC_ELEM(freq_fourier_x, j);
258  FFT_IDX2DIGFREQ(j, xdim, ux);
259  fftVRiesz[n] = ux*fftVRiesz_aux[n];
260  ++n;
261  }
262  }
263  }
264  backward_transformer->ifft(fftVRiesz.data(), MULTIDIM_ARRAY(VRiesz));
265 
267  {
269  }
270 
271  // Calculate second and third components of Riesz vector
272  n=0;
273  for(size_t k=0; k<zdimFT; ++k)
274  {
275  //uz = VEC_ELEM(freq_fourier_z, k);
276  // = VEC_ELEM(freq_fourier_z, k);
277  FFT_IDX2DIGFREQ(k, zdim, uz);
278  for(size_t i=0; i<ydimFT; ++i)
279  {
280  //uy = VEC_ELEM(freq_fourier_y, i);
281  FFT_IDX2DIGFREQ(i, ydim, uy);
282  for(size_t j=0; j<xdimFT; ++j)
283  {
284  fftVRiesz[n] = ux*fftVRiesz_aux[n];
285  fftVRiesz_aux[n] = uz*fftVRiesz_aux[n];
286  ++n;
287  }
288  }
289  }
290  backward_transformer->ifft(fftVRiesz.data(), MULTIDIM_ARRAY(VRiesz));
291 
293  {
295  }
296 
297 
298  backward_transformer->ifft(fftVRiesz_aux.data(), MULTIDIM_ARRAY(VRiesz));
299 
301  {
303  DIRECT_MULTIDIM_ELEM(amplitude, n) = std::sqrt(DIRECT_MULTIDIM_ELEM(amplitude, n));
304  }
305 
306  // Low pass filter the monogenic amplitude
307  forward_transformer->fft(MULTIDIM_ARRAY(amplitude), fftVRiesz.data());
308  float raised_w = PI/(freqL-freq);
309 
310  n = 0;
311  for(size_t k=0; k<zdimFT; ++k)
312  {
313  //uz = VEC_ELEM(freq_fourier_z, k);
314  double uz;// = VEC_ELEM(freq_fourier_z, k);
315  FFT_IDX2DIGFREQ(k, zdim, uz);
316  auto uz2 = uz*uz;
317  for(size_t i=0; i<ydimFT; ++i)
318  {
319  //uy = VEC_ELEM(freq_fourier_y, i);
320  double uy;
321  FFT_IDX2DIGFREQ(i, ydim, uy);
322  auto uy2uz2 = uz2 +uy*uy;
323  for(size_t j=0; j<xdimFT; ++j)
324  {
325  //ux = VEC_ELEM(freq_fourier_x, j);
326  double ux;
327  FFT_IDX2DIGFREQ(j, xdim, ux);
328  auto u = std::sqrt(uy2uz2 + ux*ux);
329 
330  if (u>freqL)
331  {
332  fftVRiesz[n] = 0.0f;
333  }
334  else
335  {
336  if (freqL>=u && u>=freq)
337  {
338  fftVRiesz[n] *= 0.5f*(1 + std::cos(raised_w*(u-freq)));
339  }
340  }
341  n++;
342 
343  }
344  }
345  }
346 
347  backward_transformer->ifft(fftVRiesz.data(), MULTIDIM_ARRAY(amplitude));
348 }
349 
350 
351 void ProgMonoTomo::localNoise(MultidimArray<float> &noiseMap, Matrix2D<double> &noiseMatrix, int boxsize, Matrix2D<double> &thresholdMatrix)
352 {
353 // std::cout << "Analyzing local noise" << std::endl;
354 
355  int xdim = XSIZE(noiseMap);
356  int ydim = YSIZE(noiseMap);
357 
358  int Nx = xdim/boxsize;
359  int Ny = ydim/boxsize;
360 
361 
362 
363  // For the spline regression
364  int lX=std::min(8,Nx-2), lY=std::min(8,Ny-2);
366  helper.A.initZeros(Nx*Ny,lX*lY);
367  helper.b.initZeros(Nx*Ny);
368  helper.w.initZeros(Nx*Ny);
369  helper.w.initConstant(1);
370  double hX = xdim / (double)(lX-3);
371  double hY = ydim / (double)(lY-3);
372 
373  if ( (xdim<boxsize) || (ydim<boxsize) )
374  std::cout << "Error: The tomogram in x-direction or y-direction is too small" << std::endl;
375 
376  std::vector<double> noiseVector(1);
377  std::vector<double> x,y,t;
378 
379  int xLimit, yLimit, xStart, yStart;
380 
381  long counter;
382  int idxBox=0;
383 
384  for (int X_boxIdx=0; X_boxIdx<Nx; ++X_boxIdx)
385  {
386  if (X_boxIdx==Nx-1)
387  {
388  xStart = STARTINGX(noiseMap) + X_boxIdx*boxsize;
389  xLimit = FINISHINGX(noiseMap);
390  }
391  else
392  {
393  xStart = STARTINGX(noiseMap) + X_boxIdx*boxsize;
394  xLimit = STARTINGX(noiseMap) + (X_boxIdx+1)*boxsize;
395  }
396 
397  for (int Y_boxIdx=0; Y_boxIdx<Ny; ++Y_boxIdx)
398  {
399  if (Y_boxIdx==Ny-1)
400  {
401  yStart = STARTINGY(noiseMap) + Y_boxIdx*boxsize;
402  yLimit = FINISHINGY(noiseMap);
403  }
404  else
405  {
406  yStart = STARTINGY(noiseMap) + Y_boxIdx*boxsize;
407  yLimit = STARTINGY(noiseMap) + (Y_boxIdx+1)*boxsize;
408  }
409 
410 
411 
412  counter = 0;
413  for (int i = yStart; i<yLimit; i++)
414  {
415  for (int j = xStart; j<xLimit; j++)
416  {
417  for (int k = STARTINGZ(noiseMap); k<FINISHINGZ(noiseMap); k++)
418  {
419  if (counter%257 == 0) //we take one voxel each 257 (prime number) points to reduce noise data
420  noiseVector.push_back( A3D_ELEM(noiseMap, k, i, j) );
421  ++counter;
422  }
423  }
424  }
425 
426  std::sort(noiseVector.begin(),noiseVector.end());
427  noiseMatrix.initZeros(Ny, Nx);
428 
429  MAT_ELEM(noiseMatrix, Y_boxIdx, X_boxIdx) = noiseVector[size_t(noiseVector.size()*significance)];
430 
431  double tileCenterY=0.5*(yLimit+yStart)-STARTINGY(noiseMap); // Translated to physical coordinates
432  double tileCenterX=0.5*(xLimit+xStart)-STARTINGX(noiseMap);
433  // Construction of the spline equation system
434  long idxSpline=0;
435  for(int controlIdxY = -1; controlIdxY < (lY - 1); ++controlIdxY)
436  {
437  double tmpY = Bspline03((tileCenterY / hY) - controlIdxY);
438  VEC_ELEM(helper.b,idxBox)=MAT_ELEM(noiseMatrix, Y_boxIdx, X_boxIdx);
439  if (tmpY == 0.0)
440  {
441  idxSpline+=lX;
442  continue;
443  }
444 
445  for(int controlIdxX = -1; controlIdxX < (lX - 1); ++controlIdxX)
446  {
447  double tmpX = Bspline03((tileCenterX / hX) - controlIdxX);
448  MAT_ELEM(helper.A,idxBox,idxSpline) = tmpY * tmpX;
449  idxSpline+=1;
450  }
451  }
452  x.push_back(tileCenterX);
453  y.push_back(tileCenterY);
454  t.push_back(MAT_ELEM(noiseMatrix, Y_boxIdx, X_boxIdx));
455  noiseVector.clear();
456  idxBox+=1;
457  }
458  }
459 
460 
461  // Spline coefficients
462  Matrix1D<double> cij;
463  weightedLeastSquares(helper, cij);
464 
465  thresholdMatrix.initZeros(ydim, xdim);
466 
467  for (int i=0; i<ydim; ++i)
468  {
469  for (int j=0; j<xdim; ++j)
470  {
471  long idxSpline=0;
472 
473  for(int controlIdxY = -1; controlIdxY < (lY - 1); ++controlIdxY)
474  {
475  double tmpY = Bspline03((i / hY) - controlIdxY);
476 
477  if (tmpY == 0.0)
478  {
479  idxSpline+=lX;
480  continue;
481  }
482 
483  double xContrib=0.0;
484  for(int controlIdxX = -1; controlIdxX < (lX - 1); ++controlIdxX)
485  {
486  double tmpX = Bspline03((j / hX) - controlIdxX);
487  xContrib+=VEC_ELEM(cij,idxSpline) * tmpX;// *tmpY;
488  idxSpline+=1;
489  }
490  MAT_ELEM(thresholdMatrix,i,j)+=xContrib*tmpY;
491  }
492  }
493  }
494 }
495 
496 
497 
498 
500  std::vector<float> &list)
501 {
502  MultidimArray<float> resolutionVol_aux = resolutionVol;
503  float init_res, last_res;
504 
505  init_res = list[0];
506  last_res = list[(list.size()-1)];
507 
508  auto last_resolution_2 = list[last_res];
509 
510  double lowest_res;
511  lowest_res = list[1]; //Example resolutions between 10-300, list(0)=300, list(1)=290, it is used list(1) due to background
512  //is at 300 and the smoothing cast values of 299 and they must be removed.
513 
514  // Count number of voxels with resolution
515  std::vector<float> resolVec(0);
516  float rVol;
518  {
519  rVol = DIRECT_MULTIDIM_ELEM(resolutionVol, n);
520  if ( (rVol>=(last_resolution_2-0.001)) && (rVol<=lowest_res) ) //the value 0.001 is a tolerance
521  {
522  resolVec.push_back(rVol);
523  }
524  }
525 
526  size_t N;
527  N = resolVec.size();
528  std::sort(resolVec.begin(), resolVec.end());
529 
530  std::cout << "median Resolution = " << resolVec[(int)(0.5*N)] << std::endl;
531 }
532 
533 
534 
536  std::vector<float> &list, float &cut_value, float &resolutionThreshold)
537 {
538  double last_resolution_2 = list[(list.size()-1)];
539 
540  double lowest_res;
541  lowest_res = list[0];
542 
543  // Count number of voxels with resolution
544 
545  double rVol;
546  std::vector<double> resolVec(0);
548  {
549  rVol = DIRECT_MULTIDIM_ELEM(resolutionVol, n);
550  if (rVol>=(last_resolution_2-0.001))//&& (DIRECT_MULTIDIM_ELEM(resolutionVol, n)<lowest_res) ) //the value 0.001 is a tolerance
551  {
552  resolVec.push_back(rVol);
553  }
554 
555  }
556  size_t N;
557  N = resolVec.size();
558 
559  std::sort(resolVec.begin(), resolVec.end());
560 
561  resolutionThreshold = resolVec[(int)((0.95)*N)];
562 
563  std::cout << "resolutionThreshold = " << resolutionThreshold << std::endl;
564 }
565 
566 
568 {
569  float isigma2 = (sigma*sigma);
570 
572  size_t n=0;
573  for(size_t k=0; k<zdimFT; ++k)
574  {
575  //const auto uz = VEC_ELEM(freq_fourier_z, k);
576  double uz;
577  FFT_IDX2DIGFREQ(k, zdim, uz);
578  auto uz2 = uz*uz;
579 
580  for(size_t i=0; i<ydimFT; ++i)
581  {
582  //const auto uy = VEC_ELEM(freq_fourier_y, i);
583  double uy;
584  FFT_IDX2DIGFREQ(i, ydim, uy);
585  double uy2uz2 = uz2 +uy*uy;
586  for(size_t j=0; j<xdimFT; ++j)
587  {
588  //const auto ux = VEC_ELEM(freq_fourier_x, j);
589  double ux;
590  FFT_IDX2DIGFREQ(j, xdim, ux);
591  const float u2 = (float) (uy2uz2 + ux*ux);
592 
593  fftVRiesz[n] *= std::exp(-PI*PI*u2*isigma2);
594 
595  n++;
596 
597  }
598  }
599  }
600 
601  backward_transformer->ifft(fftVRiesz.data(), MULTIDIM_ARRAY(VRiesz));
603  {
604  DIRECT_MULTIDIM_ELEM(VRiesz, n) /= xdim*ydim*zdim;
605  }
606 }
607 
608 void ProgMonoTomo::run()
609 {
610  produceSideInfo();
611 
612  MultidimArray<int> &pMask = mask();
613  MultidimArray<float> outputResolution;
614 
615  outputResolution.initZeros(1, zdim, ydim, xdim);
616  outputResolution.initConstant(maxRes);
617 
618  MultidimArray<float> amplitudeMS, amplitudeMN;
619 
620  float criticalZ = (float) icdf_gauss(significance);
621  double criticalW=-1;
622  double resolution_2;
623  float resolution, last_resolution = 10000;
624  double freq, freqH, freqL;
625  double max_meanS = -1e38;
626  float cut_value = 0.025;
627  int boxsize = 50;
628 
629  float Nyquist = 2*sampling;
630  if (minRes<2*sampling)
631  minRes = Nyquist;
632 
633  bool doNextIteration=true;
634 
635  bool lefttrimming = false;
636  int last_fourier_idx = -1;
637 
638  int count_res = 0;
639  FileName fnDebug;
640 
641  int iter=0;
642  std::vector<float> list;
643 
644  std::cout << "Analyzing frequencies" << std::endl;
645  std::cout << " " << std::endl;
646  std::vector<float> noiseValues;
647  float lastResolution = 1e38;
648 
649  size_t maxIdx = std::max(xdim, ydim);
650 
651  for (size_t idx = 0; idx<maxIdx; idx++)
652  {
653  float candidateResolution = maxRes - idx*resStep;
654 
655  if (candidateResolution<=minRes)
656  {
657  freq = 0.5;
658  }
659  else
660  {
661  freq = sampling/candidateResolution;
662  }
663 
664  int fourier_idx;
665  DIGFREQ2FFT_IDX(freq, zdim, fourier_idx);
666  FFT_IDX2DIGFREQ(fourier_idx, zdim, freq);
667 
668  resolution = sampling/freq;
669 
670  if (lastResolution-resolution<resStep)
671  {
672  continue;
673  }else
674  {
675  lastResolution = resolution;
676  }
677 
678  freqL = sampling/(resolution + resStep);
679 
680  int fourier_idx_freqL;
681  DIGFREQ2FFT_IDX(freqL, zdim, fourier_idx_freqL);
682 
683  if (fourier_idx_freqL == fourier_idx)
684  {
685  if (fourier_idx > 0){
686  FFT_IDX2DIGFREQ(fourier_idx - 1, zdim, freqL);
687  }
688  else{
689  freqL = sampling/(resolution + resStep);
690  }
691  }
692 
693  list.push_back(resolution);
694 
695  if (iter <2)
696  resolution_2 = maxRes;
697  else
698  resolution_2 = list[iter - 2];
699 
700  freqL = freq + 0.01;
701  freqH = freq - 0.01;
702 
703  fnDebug = formatString("Signal_%i.mrc", idx);
704  amplitudeMonogenicSignal3D(fourierSignal, freq, freqH, freqL, amplitudeMS, idx, fnDebug);
705 
706  fnDebug = formatString("Noise_%i.mrc", idx);
707  amplitudeMonogenicSignal3D(fourierNoise, freq, freqH, freqL, amplitudeMN, idx, fnDebug);
708 
709  Matrix2D<double> noiseMatrix;
710  Matrix2D<double> thresholdMatrix;
711  localNoise(amplitudeMN, noiseMatrix, boxsize, thresholdMatrix);
712 
713 
714  float sumS=0, sumS2=0, sumN=0, sumN2=0, NN = 0, NS = 0;
715  noiseValues.clear();
716 
718  {
719  if (DIRECT_MULTIDIM_ELEM(pMask, n)>=1)
720  {
721  float amplitudeValue=DIRECT_MULTIDIM_ELEM(amplitudeMS, n);
722  float amplitudeValueN=DIRECT_MULTIDIM_ELEM(amplitudeMN, n);
723  sumS += amplitudeValue;
724  noiseValues.push_back(amplitudeValueN);
725  sumN += amplitudeValueN;
726  ++NS;
727  ++NN;
728  }
729  }
730 
731  if (NS == 0)
732  {
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;
736  break;
737  }
738 
739  double meanS=sumS/NS;
740 
741  if (meanS>max_meanS)
742  max_meanS = meanS;
743 
744  if (meanS<0.001*max_meanS)
745  {
746  std::cout << "Search of resolutions stopped due to too low signal" << std::endl;
747  break;
748  }
749 
750  std::cout << "resolution = " << resolution << " resolution_2 = " << resolution_2 << std::endl;
751 
753  {
754  if (DIRECT_A3D_ELEM(pMask, k,i,j)>=1)
755  {
756  if ( DIRECT_A3D_ELEM(amplitudeMS, k,i,j)>(float) MAT_ELEM(thresholdMatrix, i, j) )
757  {
758 
759  DIRECT_A3D_ELEM(pMask, k,i,j) = 1;
760  DIRECT_A3D_ELEM(outputResolution, k,i,j) = resolution;
761  }
762  else{
763  DIRECT_A3D_ELEM(pMask, k,i,j) += 1;
764  if (DIRECT_A3D_ELEM(pMask, k,i,j) >2)
765  {
766  DIRECT_A3D_ELEM(pMask, k,i,j) = -1;
767  DIRECT_A3D_ELEM(outputResolution, k,i,j) = resolution_2;
768  }
769  }
770  }
771  }
772  iter++;
773 // */
774 
775  }
776 
777  Image<float> outputResolutionImage2;
778  outputResolutionImage2() = outputResolution;
779  outputResolutionImage2.write("local.mrc");
780 
781  amplitudeMN.clear();
782  amplitudeMS.clear();
783 
784  //Convolution with a real gaussian to get a smooth map
785  float sigma = 3.0f;
786  gaussFilter(outputResolution, 3.0f, VRiesz);
787  float resolutionThreshold;
788 
789  lowestResolutionbyPercentile(VRiesz, list, cut_value, resolutionThreshold);
790 
791 
793  {
794  auto resVal = DIRECT_MULTIDIM_ELEM(outputResolution, n);
795  auto value = DIRECT_MULTIDIM_ELEM(VRiesz, n);
796  if ( (value<resolutionThreshold) && (value>resVal) )
797  value = resVal;
798  if ( value<Nyquist)
799  value = Nyquist;
800  DIRECT_MULTIDIM_ELEM(VRiesz, n) = value;
801  }
802 
803  gaussFilter(VRiesz, 3.0f, VRiesz);
804 
805 
807  {
808  auto resVal = DIRECT_MULTIDIM_ELEM(outputResolution, n);
809  auto value = DIRECT_MULTIDIM_ELEM(VRiesz, n);
810  if ( (value<resolutionThreshold) && (value>resVal) )
811  value = resVal;
812  if ( value<Nyquist)
813  value = Nyquist;
814  DIRECT_MULTIDIM_ELEM(VRiesz, n) = value;
815  }
816  Image<double> outputResolutionImage;
817  MultidimArray<double> resolutionFiltered, resolutionChimera;
818 
820  outputResolutionImage2() = VRiesz;
821  outputResolutionImage2.write(fnOut);
822 
823 
824 
825 }
#define YSIZE(v)
void min(Image< double > &op1, const Image< double > &op2)
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
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)
#define FINISHINGX(v)
void resizeNoCopy(const MultidimArray< T1 > &v)
void sqrt(Image< double > &op)
static double * y
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 initConstant(T val)
void abs(Image< double > &op)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY3D(V)
#define FINISHINGZ(v)
#define DIGFREQ2FFT_IDX(freq, size, idx)
Definition: xmipp_fft.h:61
glob_prnt iter
#define STARTINGX(v)
doublereal * x
#define i
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 STARTINGY(v)
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
#define A3D_ELEM(V, k, i, j)
Matrix1D< double > b
const char * getParam(const char *param, int arg=0)
double * f
Matrix2D< double > A
void smoothBorders(MultidimArray< float > &vol, MultidimArray< int > &pMask)
#define XSIZE(v)
double Bspline03(double Argument)
void max(Image< double > &op1, const Image< double > &op2)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define ZSIZE(v)
Image< int > mask
#define DIRECT_MULTIDIM_ELEM(v, n)
std::vector< std::complex< float > > fourierSignal
void initZeros()
Definition: matrix1d.h:592
std::unique_ptr< AFT< float > > backward_transformer
void sort(struct DCEL_T *dcel)
Definition: sorting.cpp:18
#define DIRECT_A3D_ELEM(v, k, i, j)
void amplitudeMonogenicSignal3D(MultidimArray< std::complex< double > > &myfftV, double freq, double freqH, double freqL, MultidimArray< double > &amplitude, int count, FileName fnDebug)
__device__ float FFT_IDX2DIGFREQ(int idx, int size)
#define j
MultidimArray< std::complex< double > > fftVRiesz
#define FINISHINGY(v)
std::vector< std::complex< float > > fourierNoise
String formatString(const char *format,...)
void initZeros()
Definition: matrix2d.h:626
doublereal * u
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)
#define PI
Definition: tools.h:43
void weightedLeastSquares(WeightedLeastSquaresHelper &h, Matrix1D< double > &result)
int getIntParam(const char *param, int arg=0)
void initConstant(T val)
Definition: matrix1d.cpp:83
#define STARTINGZ(v)
int * n
void clear()
Definition: xmipp_image.h:144
void addParamsLine(const String &line)
void postProcessingLocalResolutions(MultidimArray< double > &resolutionVol, std::vector< double > &list)