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  * Carlos Oscar S. Sorzano coss@cnb.csic.es (2019)
5  *
6  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21  * 02111-1307 USA
22  *
23  * All comments concerning this program package may be sent to the
24  * e-mail address 'xmipp@cnb.csic.es'
25  ***************************************************************************/
26 
27 #include "resolution_monotomo.h"
28 #include <core/bilib/kernel.h>
30 //#define DEBUG
31 //#define DEBUG_MASK
32 //#define TEST_FRINGES
33 
34 
35 
37 {
38  fnVol = getParam("--vol");
39  fnVol2 = getParam("--vol2");
40  fnMeanVol = getParam("--meanVol");
41  fnOut = getParam("-o");
42  fnFilt = getParam("--filteredMap");
43  fnMask = getParam("--mask");
44  sampling = getDoubleParam("--sampling_rate");
45  fnmaskWedge = getParam("--maskWedge");
46  minRes = getDoubleParam("--minRes");
47  maxRes = getDoubleParam("--maxRes");
48  freq_step = getDoubleParam("--step");
49  trimBound = getDoubleParam("--trimmed");
50  significance = getDoubleParam("--significance");
51  nthrs = getIntParam("--threads");
52 }
53 
54 
56 {
57  addUsageLine("This function determines the local resolution of a tomogram. It makes use of two reconstructions, odd and even. The difference between them"
58  "gives a noise reconstruction. Thus, by computing the local amplitude of the signal at different frequencies and establishing a comparison with"
59  "the noise, the local resolution is computed");
60  addParamsLine(" --vol <vol_file=\"\"> : Half volume 1");
61  addParamsLine(" --vol2 <vol_file=\"\"> : Half volume 2");
62  addParamsLine(" [--mask <vol_file=\"\">] : Mask defining the signal. ");
63  addParamsLine(" -o <output=\"MGresolution.vol\"> : Local resolution volume (in Angstroms)");
64  addParamsLine(" [--maskWedge <vol_file=\"\">] : Mask containing the missing wedge in Fourier space");
65  addParamsLine(" [--filteredMap <vol_file=\"\">] : Local resolution volume filtered considering the missing wedge (in Angstroms)");
66  addParamsLine(" --meanVol <vol_file=\"\"> : Mean volume of half1 and half2 (only it is necessary the two haves are used)");
67  addParamsLine(" [--sampling_rate <s=1>] : Sampling rate (A/px)");
68  addParamsLine(" [--step <s=0.25>] : The resolution is computed at a number of frequencies between minimum and");
69  addParamsLine(" : maximum resolution px/A. This parameter determines that number");
70  addParamsLine(" [--minRes <s=30>] : Minimum resolution (A)");
71  addParamsLine(" [--maxRes <s=1>] : Maximum resolution (A)");
72  addParamsLine(" [--trimmed <s=0.5>] : Trimming percentile");
73  addParamsLine(" [--significance <s=0.95>] : The level of confidence for the hypothesis test.");
74  addParamsLine(" [--threads <s=4>] : Number of threads");
75 }
76 
77 
79 {
80  std::cout << "Starting..." << std::endl;
81  std::cout << " " << std::endl;
82  std::cout << "IMPORTANT: If the angular step of the tilt series is higher than 3 degrees"<< std::endl;
83  std::cout << " then, the tomogram is not properly for MonoTomo. Despite this is not "<< std::endl;
84  std::cout << " optimal, MonoTomo will try to compute the local resolution." << std::endl;
85  std::cout << " " << std::endl;
86 
87  Image<double> V;
88  Image<double> V1, V2;
89  V1.read(fnVol);
90  V2.read(fnVol2);
91  V()=0.5*(V1()+V2());
92  V.write(fnMeanVol);
93 
94  V().setXmippOrigin();
95 
97 
98  FourierTransformer transformer;
99  MultidimArray<double> &inputVol = V();
100  VRiesz.resizeNoCopy(inputVol);
101 
102  #ifdef TEST_FRINGES
103 
104  double modulus, xx, yy, zz;
105 
106  long nnn=0;
107  for(size_t k=0; k<ZSIZE(inputVol); ++k)
108  {
109  zz = (k-ZSIZE(inputVol)*0.5)*(k-ZSIZE(inputVol)*0.5);
110  for(size_t i=0; i<YSIZE(inputVol); ++i)
111  {
112  yy = (i-YSIZE(inputVol)*0.5)*(i-YSIZE(inputVol)*0.5);
113  for(size_t j=0; j<XSIZE(inputVol); ++j)
114  {
115  xx = (j-XSIZE(inputVol)*0.5)*(j-XSIZE(inputVol)*0.5);
116  DIRECT_MULTIDIM_ELEM(inputVol,nnn) = cos(0.1*sqrt(xx+yy+zz));
117  ++nnn;
118  }
119  }
120  }
121 
122  Image<double> saveiu;
123  saveiu = inputVol;
124  saveiu.write("franjas.vol");
125  exit(0);
126  #endif
127 
128 
129  transformer.FourierTransform(inputVol, fftV);
130  iu.initZeros(fftV);
131 
132  // Calculate u and first component of Riesz vector
133  double uz, uy, ux, uz2, u2, uz2y2;
134  long n=0;
135  for(size_t k=0; k<ZSIZE(fftV); ++k)
136  {
137  FFT_IDX2DIGFREQ(k,ZSIZE(inputVol),uz);
138  uz2=uz*uz;
139 
140  for(size_t i=0; i<YSIZE(fftV); ++i)
141  {
142  FFT_IDX2DIGFREQ(i,YSIZE(inputVol),uy);
143  uz2y2=uz2+uy*uy;
144 
145  for(size_t j=0; j<XSIZE(fftV); ++j)
146  {
147  FFT_IDX2DIGFREQ(j,XSIZE(inputVol),ux);
148  u2=uz2y2+ux*ux;
149  if ((k != 0) || (i != 0) || (j != 0))
150  DIRECT_MULTIDIM_ELEM(iu,n) = 1.0/sqrt(u2);
151  else
152  DIRECT_MULTIDIM_ELEM(iu,n) = 1e38;
153  ++n;
154  }
155  }
156  }
157  #ifdef DEBUG
158  Image<double> saveiu;
159  saveiu = 1/iu;
160  saveiu.write("iu.vol");
161  #endif
162 
163  // Prepare low pass filter
165  lowPassFilter.raised_w = 0.01;
168 
169  // Prepare mask
170  MultidimArray<int> &pMask=mask();
171 
172  if (fnMask != "")
173  {
174  mask.read(fnMask);
175  mask().setXmippOrigin();
176  }
177  else
178  {
179  size_t Zdim, Ydim, Xdim, Ndim;
180  inputVol.getDimensions(Xdim, Ydim, Zdim, Ndim);
181  mask().resizeNoCopy(Ndim, Zdim, Ydim, Xdim);
182  mask().initConstant(1);
183  }
184 
186 
188  {
189  if (A3D_ELEM(pMask, k, i, j) == 1)
191 // if (i*i+j*j+k*k > R*R)
192 // A3D_ELEM(pMask, k, i, j) = -1;
193  }
194 
195  #ifdef DEBUG_MASK
196  mask.write("mask.vol");
197  #endif
198 
199 
200  V1.read(fnVol);
201  V2.read(fnVol2);
202 
203  V1()-=V2();
204  V1()/=2;
205 
207  FourierTransformer transformer2;
208 
209  #ifdef DEBUG
210  V1.write("diff_volume.vol");
211  #endif
212 
213  int N_smoothing = 10;
214 
215  int siz_z = ZSIZE(inputVol)*0.5;
216  int siz_y = YSIZE(inputVol)*0.5;
217  int siz_x = XSIZE(inputVol)*0.5;
218 
219 
220  int limit_distance_x = (siz_x-N_smoothing);
221  int limit_distance_y = (siz_y-N_smoothing);
222  int limit_distance_z = (siz_z-N_smoothing);
223 
224  n=0;
225  for(int k=0; k<ZSIZE(inputVol); ++k)
226  {
227  uz = (k - siz_z);
228  for(int i=0; i<YSIZE(inputVol); ++i)
229  {
230  uy = (i - siz_y);
231  for(int j=0; j<XSIZE(inputVol); ++j)
232  {
233  ux = (j - siz_x);
234 
235  if (abs(ux)>=limit_distance_x)
236  {
237  DIRECT_MULTIDIM_ELEM(V1(), n) *= 0.5*(1+cos(PI*(limit_distance_x - abs(ux))/N_smoothing));
238  DIRECT_MULTIDIM_ELEM(pMask, n) = 0;
239  }
240  if (abs(uy)>=limit_distance_y)
241  {
242  DIRECT_MULTIDIM_ELEM(V1(), n) *= 0.5*(1+cos(PI*(limit_distance_y - abs(uy))/N_smoothing));
243  DIRECT_MULTIDIM_ELEM(pMask, n) = 0;
244  }
245  if (abs(uz)>=limit_distance_z)
246  {
247  DIRECT_MULTIDIM_ELEM(V1(), n) *= 0.5*(1+cos(PI*(limit_distance_z - abs(uz))/N_smoothing));
248  DIRECT_MULTIDIM_ELEM(pMask, n) = 0;
249  }
250  ++n;
251  }
252  }
253  }
254 
255 
256  transformer2.FourierTransform(V1(), *fftN);
257 
258  V.clear();
259 
260  double u;
261 
265 
266  VEC_ELEM(freq_fourier_z,0) = 1e-38;
267  for(size_t k=0; k<ZSIZE(fftV); ++k)
268  {
269  FFT_IDX2DIGFREQ(k,ZSIZE(pMask), u);
271  }
272 
273  VEC_ELEM(freq_fourier_y,0) = 1e-38;
274  for(size_t k=0; k<YSIZE(fftV); ++k)
275  {
276  FFT_IDX2DIGFREQ(k,YSIZE(pMask), u);
278  }
279 
280  VEC_ELEM(freq_fourier_x,0) = 1e-38;
281  for(size_t k=0; k<XSIZE(fftV); ++k)
282  {
283  FFT_IDX2DIGFREQ(k,XSIZE(pMask), u);
285  }
286 
287 }
288 
289 
290 void ProgMonoTomo::amplitudeMonogenicSignal3D(MultidimArray< std::complex<double> > &myfftV,
291  double freq, double freqH, double freqL, MultidimArray<double> &amplitude, int count, FileName fnDebug)
292 {
293  fftVRiesz.initZeros(myfftV);
294  fftVRiesz_aux.initZeros(myfftV);
295  std::complex<double> J(0,1);
296 
297  // Filter the input volume and add it to amplitude
298  long n=0;
299  double ideltal=PI/(freq-freqH);
300 
302  {
303  double iun=DIRECT_MULTIDIM_ELEM(iu,n);
304  double un=1.0/iun;
305  if (freqH<=un && un<=freq)
306  {
307  //double H=0.5*(1+cos((un-w1)*ideltal));
309  DIRECT_MULTIDIM_ELEM(fftVRiesz, n) *= 0.5*(1+cos((un-freq)*ideltal));//H;
313  } else if (un>freq)
314  {
319  }
320  }
321 
323 
324  #ifdef DEBUG
325  Image<double> filteredvolume;
326  filteredvolume = VRiesz;
327  filteredvolume.write(formatString("Volumen_filtrado_%i.vol", count));
328 
329  FileName iternumber;
330  iternumber = formatString("_Volume_%i.vol", count);
331  Image<double> saveImg2;
332  saveImg2() = VRiesz;
333  if (fnDebug.c_str() != "")
334  {
335  saveImg2.write(fnDebug+iternumber);
336  }
337  saveImg2.clear();
338  #endif
339 
340  amplitude.resizeNoCopy(VRiesz);
341 
344 
345  // Calculate first component of Riesz vector
346  double uz, uy, ux;
347  n=0;
348  for(size_t k=0; k<ZSIZE(myfftV); ++k)
349  {
350  for(size_t i=0; i<YSIZE(myfftV); ++i)
351  {
352  for(size_t j=0; j<XSIZE(myfftV); ++j)
353  {
354  ux = VEC_ELEM(freq_fourier_x,j);
356  ++n;
357  }
358  }
359  }
363 
364  // Calculate second and third components of Riesz vector
365  n=0;
366  for(size_t k=0; k<ZSIZE(myfftV); ++k)
367  {
368  uz = VEC_ELEM(freq_fourier_z,k);
369  for(size_t i=0; i<YSIZE(myfftV); ++i)
370  {
371  uy = VEC_ELEM(freq_fourier_y,i);
372  for(size_t j=0; j<XSIZE(myfftV); ++j)
373  {
376  ++n;
377  }
378  }
379  }
381 
384 
386 
388  {
390  DIRECT_MULTIDIM_ELEM(amplitude,n)=sqrt(DIRECT_MULTIDIM_ELEM(amplitude,n));
391  }
392  #ifdef DEBUG
393  if (fnDebug.c_str() != "")
394  {
395  Image<double> saveImg;
396  saveImg = amplitude;
397  FileName iternumber;
398  iternumber = formatString("_Amplitude_%i.vol", count);
399  saveImg.write(fnDebug+iternumber);
400  saveImg.clear();
401  }
402  #endif // DEBUG
403 //
404  // Low pass filter the monogenic amplitude
405  transformer_inv.FourierTransform(amplitude, fftVRiesz, false);
406  double raised_w = PI/(freqL-freq);
407 
408  n=0;
409 
411  {
412  double un=1.0/DIRECT_MULTIDIM_ELEM(iu,n);
413  if (freqL>=un && un>=freq)
414  {
415  DIRECT_MULTIDIM_ELEM(fftVRiesz,n) *= 0.5*(1 + cos(raised_w*(un-freq)));
416  }
417  else
418  {
419  if (un>freqL)
420  {
422  }
423  }
424  }
426 
427 
428  #ifdef DEBUG
429  Image<double> saveImg2;
430  saveImg2 = amplitude;
431  FileName fnSaveImg2;
432  if (fnDebug.c_str() != "")
433  {
434  iternumber = formatString("_Filtered_Amplitude_%i.vol", count);
435  saveImg2.write(fnDebug+iternumber);
436  }
437  saveImg2.clear();
438  #endif // DEBUG
439 }
440 
441 
442 void ProgMonoTomo::localNoise(MultidimArray<double> &noiseMap, Matrix2D<double> &noiseMatrix, int boxsize, Matrix2D<double> &thresholdMatrix)
443 {
444 // std::cout << "Analyzing local noise" << std::endl;
445 
446  int xdim = XSIZE(noiseMap);
447  int ydim = YSIZE(noiseMap);
448 
449  int Nx = xdim/boxsize;
450  int Ny = ydim/boxsize;
451 
452  noiseMatrix.initZeros(Ny, Nx);
453 
454  // For the spline regression
455  int lX=std::min(8,Nx-2), lY=std::min(8,Ny-2);
457  helper.A.initZeros(Nx*Ny,lX*lY);
458  helper.b.initZeros(Nx*Ny);
459  helper.w.initZeros(Nx*Ny);
460  helper.w.initConstant(1);
461  double hX = xdim / (double)(lX-3);
462  double hY = ydim / (double)(lY-3);
463 
464  if ( (xdim<boxsize) || (ydim<boxsize) )
465  std::cout << "Error: The tomogram in x-direction or y-direction is too small" << std::endl;
466 
467  std::vector<double> noiseVector(1);
468  std::vector<double> x,y,t;
469 
470  int xLimit, yLimit, xStart, yStart;
471 
472  long counter;
473  int idxBox=0;
474 
475  for (int X_boxIdx=0; X_boxIdx<Nx; ++X_boxIdx)
476  {
477  if (X_boxIdx==Nx-1)
478  {
479  xStart = STARTINGX(noiseMap) + X_boxIdx*boxsize;
480  xLimit = FINISHINGX(noiseMap);
481  }
482  else
483  {
484  xStart = STARTINGX(noiseMap) + X_boxIdx*boxsize;
485  xLimit = STARTINGX(noiseMap) + (X_boxIdx+1)*boxsize;
486  }
487 
488  for (int Y_boxIdx=0; Y_boxIdx<Ny; ++Y_boxIdx)
489  {
490  if (Y_boxIdx==Ny-1)
491  {
492  yStart = STARTINGY(noiseMap) + Y_boxIdx*boxsize;
493  yLimit = FINISHINGY(noiseMap);
494  }
495  else
496  {
497  yStart = STARTINGY(noiseMap) + Y_boxIdx*boxsize;
498  yLimit = STARTINGY(noiseMap) + (Y_boxIdx+1)*boxsize;
499  }
500 
501 
502 
503  counter = 0;
504  for (int i = yStart; i<yLimit; i++)
505  {
506  for (int j = xStart; j<xLimit; j++)
507  {
508  for (int k = STARTINGZ(noiseMap); k<FINISHINGZ(noiseMap); k++)
509  {
510  if (counter%257 == 0) //we take one voxel each 257 (prime number) points to reduce noise data
511  noiseVector.push_back( A3D_ELEM(noiseMap, k, i, j) );
512  ++counter;
513  }
514  }
515  }
516 
517  std::sort(noiseVector.begin(),noiseVector.end());
518  MAT_ELEM(noiseMatrix, Y_boxIdx, X_boxIdx) = noiseVector[size_t(noiseVector.size()*significance)];
519 
520  double tileCenterY=0.5*(yLimit+yStart)-STARTINGY(noiseMap); // Translated to physical coordinates
521  double tileCenterX=0.5*(xLimit+xStart)-STARTINGX(noiseMap);
522  // Construction of the spline equation system
523  long idxSpline=0;
524  for(int controlIdxY = -1; controlIdxY < (lY - 1); ++controlIdxY)
525  {
526  double tmpY = Bspline03((tileCenterY / hY) - controlIdxY);
527  VEC_ELEM(helper.b,idxBox)=MAT_ELEM(noiseMatrix, Y_boxIdx, X_boxIdx);
528  if (tmpY == 0.0)
529  {
530  idxSpline+=lX;
531  continue;
532  }
533 
534  for(int controlIdxX = -1; controlIdxX < (lX - 1); ++controlIdxX)
535  {
536  double tmpX = Bspline03((tileCenterX / hX) - controlIdxX);
537  MAT_ELEM(helper.A,idxBox,idxSpline) = tmpY * tmpX;
538  idxSpline+=1;
539  }
540  }
541  x.push_back(tileCenterX);
542  y.push_back(tileCenterY);
543  t.push_back(MAT_ELEM(noiseMatrix, Y_boxIdx, X_boxIdx));
544  noiseVector.clear();
545  idxBox+=1;
546  }
547  }
548 
549 
550  // Spline coefficients
551  Matrix1D<double> cij;
552  weightedLeastSquares(helper, cij);
553 
554  thresholdMatrix.initZeros(ydim, xdim);
555 
556  for (int i=0; i<ydim; ++i)
557  {
558  for (int j=0; j<xdim; ++j)
559  {
560  long idxSpline=0;
561 
562  for(int controlIdxY = -1; controlIdxY < (lY - 1); ++controlIdxY)
563  {
564  double tmpY = Bspline03((i / hY) - controlIdxY);
565 
566  if (tmpY == 0.0)
567  {
568  idxSpline+=lX;
569  continue;
570  }
571 
572  double xContrib=0.0;
573  for(int controlIdxX = -1; controlIdxX < (lX - 1); ++controlIdxX)
574  {
575  double tmpX = Bspline03((j / hX) - controlIdxX);
576  xContrib+=VEC_ELEM(cij,idxSpline) * tmpX;// *tmpY;
577  idxSpline+=1;
578  }
579  MAT_ELEM(thresholdMatrix,i,j)+=xContrib*tmpY;
580  }
581  }
582  }
583 }
584 
585 
586 
588  std::vector<double> &list)
589 {
590  MultidimArray<double> resolutionVol_aux = resolutionVol;
591  double init_res, last_res;
592 
593  init_res = list[0];
594  last_res = list[(list.size()-1)];
595 
596  double last_resolution_2 = list[last_res];
597 
598  double lowest_res;
599  lowest_res = list[1]; //Example resolutions between 10-300, list(0)=300, list(1)=290, it is used list(1) due to background
600  //is at 300 and the smoothing cast values of 299 and they must be removed.
601 
602  // Count number of voxels with resolution
603  std::vector<double> resolVec(0);
604  double rVol;
606  {
607  rVol = DIRECT_MULTIDIM_ELEM(resolutionVol, n);
608  if ( (rVol>=(last_resolution_2-0.001)) && (rVol<=lowest_res) ) //the value 0.001 is a tolerance
609  {
610  resolVec.push_back(rVol);
611  }
612  }
613 
614  size_t N;
615  N = resolVec.size();
616  std::sort(resolVec.begin(), resolVec.end());
617 
618  std::cout << "median Resolution = " << resolVec[(int)(0.5*N)] << std::endl;
619 }
620 
621 
622 
624  std::vector<double> &list, double &cut_value, double &resolutionThreshold)
625 {
626  double last_resolution_2 = list[(list.size()-1)];
627 
628  double lowest_res;
629  lowest_res = list[0];
630 
631  // Count number of voxels with resolution
632 
633  double rVol;
634  std::vector<double> resolVec(0);
636  {
637  rVol = DIRECT_MULTIDIM_ELEM(resolutionVol, n);
638  if (rVol>=(last_resolution_2-0.001))//&& (DIRECT_MULTIDIM_ELEM(resolutionVol, n)<lowest_res) ) //the value 0.001 is a tolerance
639  {
640  resolVec.push_back(rVol);
641  }
642 
643  }
644  size_t N;
645  N = resolVec.size();
646 
647  std::sort(resolVec.begin(), resolVec.end());
648 
649  resolutionThreshold = resolVec[(int)((0.95)*N)];
650 
651  std::cout << "resolutionThreshold = " << resolutionThreshold << std::endl;
652 }
653 
654 
655 void ProgMonoTomo::resolution2eval(int &count_res, double step,
656  double &resolution, double &last_resolution,
657  double &freq, double &freqL,
658  int &last_fourier_idx,
659  bool &continueIter, bool &breakIter)
660 {
661  resolution = maxRes - count_res*step;
662  freq = sampling/resolution;
663  ++count_res;
664 
665  double Nyquist = 2*sampling;
666  double aux_frequency;
667  int fourier_idx;
668 
669  DIGFREQ2FFT_IDX(freq, ZSIZE(VRiesz), fourier_idx);
670 
671  FFT_IDX2DIGFREQ(fourier_idx, ZSIZE(VRiesz), aux_frequency);
672 
673  freq = aux_frequency;
674 
675  if (fourier_idx == last_fourier_idx)
676  {
677  continueIter = true;
678  return;
679  }
680 
681  last_fourier_idx = fourier_idx;
682  resolution = sampling/aux_frequency;
683 
684 
685  if (count_res == 0)
686  last_resolution = resolution;
687 
688  if (resolution<Nyquist)
689  {
690  breakIter = true;
691  return;
692  }
693 
694  freqL = sampling/(resolution + step);
695 
696  int fourier_idx_2;
697 
698  DIGFREQ2FFT_IDX(freqL, ZSIZE(VRiesz), fourier_idx_2);
699 
700  if (fourier_idx_2 == fourier_idx)
701  {
702  if (fourier_idx > 0){
703  FFT_IDX2DIGFREQ(fourier_idx - 1, ZSIZE(VRiesz), freqL);
704  }
705  else{
706  freqL = sampling/(resolution + step);
707  }
708  }
709 
710 }
711 
712 
714 {
715  produceSideInfo();
716 
717  Image<double> outputResolution;
718 
719  outputResolution().resizeNoCopy(VRiesz);
720  outputResolution().initConstant(maxRes);
721 
722  MultidimArray<int> &pMask = mask();
723  MultidimArray<double> &pOutputResolution = outputResolution();
724  MultidimArray<double> &pVfiltered = Vfiltered();
725  MultidimArray<double> &pVresolutionFiltered = VresolutionFiltered();
726  MultidimArray<double> amplitudeMS, amplitudeMN;
727 
728  double criticalZ=icdf_gauss(significance);
729  double criticalW=-1;
730  double resolution, resolution_2, last_resolution = 10000; //A huge value for achieving
731  //last_resolution < resolution
732  double freq, freqH, freqL;
733  double max_meanS = -1e38;
734  double cut_value = 0.025;
735  int boxsize = 50;
736 
737 
738  double R_ = freq_step;
739 
740  if (R_<0.25)
741  R_=0.25;
742 
743  double Nyquist = 2*sampling;
744  if (minRes<2*sampling)
745  minRes = Nyquist;
746 
747  bool doNextIteration=true;
748 
749  bool lefttrimming = false;
750  int last_fourier_idx = -1;
751 
752  int count_res = 0;
753  FileName fnDebug;
754 
755  int iter=0;
756  std::vector<double> list;
757 
758  std::cout << "Analyzing frequencies" << std::endl;
759  std::cout << " " << std::endl;
760  std::vector<double> noiseValues;
761 
762  int xdim = XSIZE(pOutputResolution);
763  int ydim = YSIZE(pOutputResolution);
764 
765  do
766  {
767  bool continueIter = false;
768  bool breakIter = false;
769 
770  resolution2eval(count_res, R_,
771  resolution, last_resolution,
772  freq, freqH,
773  last_fourier_idx, continueIter, breakIter);
774 
775  if (continueIter)
776  continue;
777 
778  if (breakIter)
779  break;
780 
781  std::cout << "resolution = " << resolution << std::endl;
782 
783 
784  list.push_back(resolution);
785 
786  if (iter <2)
787  resolution_2 = list[0];
788  else
789  resolution_2 = list[iter - 2];
790 
791  fnDebug = "Signal";
792 
793  freqL = freq + 0.01;
794 
795  amplitudeMonogenicSignal3D(fftV, freq, freqH, freqL, amplitudeMS, iter, fnDebug);
796  fnDebug = "Noise";
797  amplitudeMonogenicSignal3D(*fftN, freq, freqH, freqL, amplitudeMN, iter, fnDebug);
798 
799  Matrix2D<double> noiseMatrix;
800 
801  Matrix2D<double> thresholdMatrix;
802  localNoise(amplitudeMN, noiseMatrix, boxsize, thresholdMatrix);
803 
804 
805  double sumS=0, sumS2=0, sumN=0, sumN2=0, NN = 0, NS = 0;
806  noiseValues.clear();
807 
808 
810  {
811  if (DIRECT_MULTIDIM_ELEM(pMask, n)>=1)
812  {
813  double amplitudeValue=DIRECT_MULTIDIM_ELEM(amplitudeMS, n);
814  double amplitudeValueN=DIRECT_MULTIDIM_ELEM(amplitudeMN, n);
815  sumS += amplitudeValue;
816  noiseValues.push_back(amplitudeValueN);
817  sumN += amplitudeValueN;
818  ++NS;
819  ++NN;
820  }
821  }
822 
823  #ifdef DEBUG
824  std::cout << "NS" << NS << std::endl;
825  std::cout << "NVoxelsOriginalMask" << NVoxelsOriginalMask << std::endl;
826  std::cout << "NS/NVoxelsOriginalMask = " << NS/NVoxelsOriginalMask << std::endl;
827  #endif
828 
829 
830  if (NS == 0)
831  {
832  std::cout << "There are no points to compute inside the mask" << std::endl;
833  std::cout << "If the number of computed frequencies is low, perhaps the provided"
834  "mask is not enough tight to the volume, in that case please try another mask" << std::endl;
835  break;
836  }
837 
838  double meanS=sumS/NS;
839 
840  #ifdef DEBUG
841  std::cout << "Iteration = " << iter << ", Resolution= " << resolution <<
842  ", Signal = " << meanS << ", Noise = " << meanN << ", Threshold = "
843  << thresholdNoise <<std::endl;
844  #endif
845 
846 
847  if (meanS>max_meanS)
848  max_meanS = meanS;
849 
850  if (meanS<0.001*max_meanS)
851  {
852  std::cout << "Search of resolutions stopped due to too low signal" << std::endl;
853  break;
854  }
855 
857  {
858  if (DIRECT_A3D_ELEM(pMask, k,i,j)>=1)
859  {
860  if ( DIRECT_A3D_ELEM(amplitudeMS, k,i,j)>MAT_ELEM(thresholdMatrix, i, j) )
861  {
862 
863  DIRECT_A3D_ELEM(pMask, k,i,j) = 1;
864  DIRECT_A3D_ELEM(pOutputResolution, k,i,j) = resolution;
865  }
866  else{
867  DIRECT_A3D_ELEM(pMask, k,i,j) += 1;
868  if (DIRECT_A3D_ELEM(pMask, k,i,j) >2)
869  {
870  DIRECT_A3D_ELEM(pMask, k,i,j) = -1;
871  DIRECT_A3D_ELEM(pOutputResolution, k,i,j) = resolution_2;
872  }
873  }
874  }
875  }
876 
877 
878 
879  #ifdef DEBUG_MASK
880  FileName fnmask_debug;
881  fnmask_debug = formatString("maske_%i.vol", iter);
882  mask.write(fnmask_debug);
883  #endif
884 
885 
886  if (doNextIteration)
887  {
888  if (resolution <= (minRes-0.001))
889  doNextIteration = false;
890  }
891 
892 // }
893  iter++;
894  last_resolution = resolution;
895  } while (doNextIteration);
896 
897  Image<double> outputResolutionImage2;
898  outputResolutionImage2() = pOutputResolution;
899  outputResolutionImage2.write("resultado.vol");
900 
901 
902  amplitudeMN.clear();
903  amplitudeMS.clear();
904 
905  //Convolution with a real gaussian to get a smooth map
906  MultidimArray<double> FilteredResolution = pOutputResolution;
907  double sigma = 25.0;
908 
909  double resolutionThreshold;
910 
911  sigma = 3;
912 
913  realGaussianFilter(FilteredResolution, sigma);
914 
915 
916  lowestResolutionbyPercentile(FilteredResolution, list, cut_value, resolutionThreshold);
917 
918 
919  FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(FilteredResolution)
920  {
921  if ( (DIRECT_MULTIDIM_ELEM(FilteredResolution, n)<resolutionThreshold) && (DIRECT_MULTIDIM_ELEM(FilteredResolution, n)>DIRECT_MULTIDIM_ELEM(pOutputResolution, n)) )
922  DIRECT_MULTIDIM_ELEM(FilteredResolution, n) = DIRECT_MULTIDIM_ELEM(pOutputResolution, n);
923  if ( DIRECT_MULTIDIM_ELEM(FilteredResolution, n)<Nyquist)
924  DIRECT_MULTIDIM_ELEM(FilteredResolution, n) = Nyquist;
925  }
926 
927  realGaussianFilter(FilteredResolution, sigma);
928 
929 
930  FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(FilteredResolution)
931  {
932  if ((DIRECT_MULTIDIM_ELEM(FilteredResolution, n)<resolutionThreshold) && (DIRECT_MULTIDIM_ELEM(FilteredResolution, n)>DIRECT_MULTIDIM_ELEM(pOutputResolution, n)))
933  DIRECT_MULTIDIM_ELEM(FilteredResolution, n) = DIRECT_MULTIDIM_ELEM(pOutputResolution, n);
934  if ( DIRECT_MULTIDIM_ELEM(FilteredResolution, n)<Nyquist)
935  DIRECT_MULTIDIM_ELEM(FilteredResolution, n) = Nyquist;
936  }
937  Image<double> outputResolutionImage;
938  MultidimArray<double> resolutionFiltered, resolutionChimera;
939 
940  postProcessingLocalResolutions(FilteredResolution, list);
941  outputResolutionImage() = FilteredResolution;
942  outputResolutionImage.write(fnOut);
943 }
FourierTransformer transformer_inv
#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)
double getDoubleParam(const char *param, int arg=0)
void resolution2eval(int &count_res, double step, double &resolution, double &last_resolution, double &freq, double &freqL, int &last_fourier_idx, bool &continueIter, bool &breakIter)
void inverseFourierTransform()
Definition: xmipp_fftw.cpp:329
void localNoise(MultidimArray< double > &noiseMap, Matrix2D< double > &noiseMatrix, int boxsize, Matrix2D< double > &thresholdMatrix)
#define FINISHINGX(v)
Matrix1D< double > freq_fourier_z
void setThreadsNumber(int tNumber)
Definition: xmipp_fftw.h:119
Image< double > VresolutionFiltered
void resizeNoCopy(const MultidimArray< T1 > &v)
void sqrt(Image< double > &op)
static double * y
MultidimArray< double > iu
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)
void abs(Image< double > &op)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY3D(V)
#define FINISHINGZ(v)
glob_prnt iter
#define DIGFREQ2FFT_IDX(freq, size, idx)
Definition: xmipp_fft.h:61
#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)
#define FOR_ALL_ELEMENTS_IN_ARRAY3D(V)
Matrix1D< double > b
const char * getParam(const char *param, int arg=0)
Matrix1D< double > freq_fourier_y
Matrix2D< double > A
#define XSIZE(v)
FourierFilter lowPassFilter
double Bspline03(double Argument)
#define RAISED_COSINE
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define ZSIZE(v)
Image< int > mask
#define DIRECT_MULTIDIM_ELEM(v, n)
MultidimArray< std::complex< double > > * fftN
MultidimArray< std::complex< double > > fftV
void initZeros()
Definition: matrix1d.h:592
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)
void FourierTransform(T &v, T1 &V, bool getCopy=true)
Definition: xmipp_fftw.h:166
__device__ float FFT_IDX2DIGFREQ(int idx, int size)
#define j
MultidimArray< std::complex< double > > fftVRiesz
#define FINISHINGY(v)
void realGaussianFilter(MultidimArray< double > &img, double sigma)
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)
Matrix1D< double > freq_fourier_x
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
#define LOWPASS
void addParamsLine(const String &line)
Image< double > Vfiltered
void postProcessingLocalResolutions(MultidimArray< double > &resolutionVol, std::vector< double > &list)
void getDimensions(size_t &Xdim, size_t &Ydim, size_t &Zdim, size_t &Ndim) const