Xmipp  v3.23.11-Nereus
monogenic_signal.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Jose Luis Vilas (jlvilas@cnb.csic.es)
4  *
5  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  * 02111-1307 USA
21  *
22  * All comments concerning this program package may be sent to the
23  * e-mail address 'xmipp@cnb.csic.es'
24  ***************************************************************************/
25 #include "monogenic_signal.h"
26 #include "core/xmipp_image.h"
27 #include "core/xmipp_fftw.h"
28 #include <random>
29 #include <algorithm>
30 
31 
32 // This function takes as input a "mask" and returns the radius and the volumen "vol" of the
33 // protein. The radius is defines has the distance from the center of the cube to the farthest
34 // point of the protein measured from the center. The volumen "vol" represent the number of
35 // voxels of the mask
37  long &vol)
38 {
39  vol = 0;
40  radius = 0;
42  {
43 
44  if (A3D_ELEM(mask, k, i, j) == 1)
45  {
46  int R2 = (k*k + i*i + j*j);
47  ++vol;
48  if (R2>radius)
49  radius = R2;
50  }
51  }
52  radius = sqrt(radius);
53  std::cout << " " << std::endl;
54  std::cout << "The protein has a radius of "<< radius << " px " << std::endl;
55 }
56 
57 
58 // FINDCLIFFVALUE: This function determines the radius of noise, "radiuslimit". It means given
59 // a map, "inputmap", the radius measured from the origin for which the map is masked with a
60 // spherical mask is detected. Outside of this sphere there is no noise. Once the all voxels of
61 // of the mask with corresponding radiues greater than "radiuslimit" has been set to -1, the
62 // parameter "rsmooth" does not affect to the output of this function, it is only used to
63 // provide information to the user when the "radiuslimit" is close to the boxsize. Note that
64 // the perimeter of the box is sometimes smoothed when a Fourier Transform is carried out.
65 // To prevent this situation this parameter is provided, but it is only informative via
66 // the standard output
68  int &radius, int &radiuslimit, MultidimArray<int> &mask, double rsmooth)
69 {
70  double criticalZ = icdf_gauss(0.95);
71  radiuslimit = XSIZE(inputmap)/2;
72  double last_mean=0;
73  double last_std2=1e-38;
74 
75  for (int rad = radius; rad<radiuslimit; rad++)
76  {
77  double sum=0;
78  double sum2=0;
79  double N=0;
80  int sup;
81  int inf;
82  inf = rad*rad;
83  sup = (rad + 1)*(rad + 1);
85  {
86  double aux = k*k + i*i + j*j;
87  if ( (aux<sup) && (aux>=inf) )
88  {
89  double value = A3D_ELEM(inputmap, k, i, j);;
90  sum += value;
91  sum2 += value*value;
92  N++;
93  }
94  }
95  double mean = sum/N;
96  double std2 = sum2/N - mean*mean;
97 
98  if (std2/last_std2<0.01)
99  {
100  radiuslimit = rad - 1;
101  break;
102  }
103 
104  last_mean = mean, last_std2 = std2;
105  }
106 
107  std::cout << "There is no noise beyond a radius of " << radiuslimit << " px " << std::endl;
108  std::cout << "Regions with a radius greater than " << radiuslimit << " px will not be considered" << std::endl;
109 
110  double raux = (radiuslimit - rsmooth);
111  if (raux<=radius)
112  {
113  std::cout << "Warning: the boxsize is very close to "
114  "the protein size please provide a greater box" << std::endl;
115  }
116 
117  raux *= raux;
118 
120  {
121  double aux = k*k + i*i + j*j;
122  if (aux>=raux)
123  A3D_ELEM(mask, k, i, j) = -1;
124  }
125 
126 }
127 
128 //FOURIERFREQVECTOR: It defines a vector, freq_fourier, that contains
129 // the frequencies of the Fourier direction. Where dimarrayFourier is the
130 // number of components of the vector, and dimarrayReal is the dimensions
131 // of the map along the direction for which the fft is computed
132 Matrix1D<double> Monogenic::fourierFreqVector(size_t dimarrayFourier, size_t dimarrayReal)
133 {
134  double u;
135  Matrix1D<double> freq_fourier;
136  freq_fourier.initZeros(dimarrayFourier);
137  VEC_ELEM(freq_fourier,0) = 1e-38; //A really low value to represent 0 avooiding singularities
138  for(size_t k=1; k<dimarrayFourier; ++k){
139  FFT_IDX2DIGFREQ(k,dimarrayReal, u);
140  VEC_ELEM(freq_fourier, k) = u;
141  }
142  return freq_fourier;
143 }
144 
145 
146 //TODO: Use macros to avoid repeating code
147 //FOURIERFREQS_3D: Determine the map of frequencies in the Fourier Space as an output.
148 // Also, the accessible frequencies along each direction are calculated, they are
149 // "freq_fourier_x", "freq_fourier_y", and "freq_fourier_z".
150 MultidimArray<double> Monogenic::fourierFreqs_3D(const MultidimArray< std::complex<double> > &myfftV,
151  const MultidimArray<double> &inputVol,
152  Matrix1D<double> &freq_fourier_x,
153  Matrix1D<double> &freq_fourier_y,
154  Matrix1D<double> &freq_fourier_z)
155 {
156  freq_fourier_z = fourierFreqVector(ZSIZE(myfftV), ZSIZE(inputVol));
157  freq_fourier_y = fourierFreqVector(YSIZE(myfftV), YSIZE(inputVol));
158  freq_fourier_x = fourierFreqVector(XSIZE(myfftV), XSIZE(inputVol));
159 
161 
162  iu.initZeros(myfftV);
163 
164  double uz;
165  double uy;
166  double ux;
167  double uz2;
168  double u2;
169  double uz2y2;
170  long n=0;
171  // TODO: Take ZSIZE(myfftV) out of the loop
172  // TODO: Use freq_fourier_x instead of calling FFT_IDX2DIGFREQ
173 
174  for(size_t k=0; k<ZSIZE(myfftV); ++k)
175  {
176  FFT_IDX2DIGFREQ(k,ZSIZE(inputVol),uz);
177  uz2 = uz*uz;
178  for(size_t i=0; i<YSIZE(myfftV); ++i)
179  {
180  FFT_IDX2DIGFREQ(i,YSIZE(inputVol),uy);
181  uz2y2 = uz2 + uy*uy;
182 
183  for(size_t j=0; j<XSIZE(myfftV); ++j)
184  {
185  FFT_IDX2DIGFREQ(j,XSIZE(inputVol), ux);
186  u2 = uz2y2 + ux*ux;
187 
188  if ((k != 0) || (i != 0) || (j != 0))
189  {
190  DIRECT_MULTIDIM_ELEM(iu,n) = 1/sqrt(u2);
191  }
192  else
193  {
194  DIRECT_MULTIDIM_ELEM(iu,n) = 1e38;
195  }
196  ++n;
197  }
198  }
199  }
200 
201  return iu;
202 }
203 
204 
205 //RESOLUTION2EVAL: Determines the resoltion to be analzed in the estimation
206 //of the local resolution. These resolution are freq, freqL (digital units)
207 // being freqL the tail of the raise cosine centered at freq. The parameter
208 // resolution is the frequency freq in converted into Angstrom. The parameters
209 //minRes and maxRes, determines the limits of the resolution range to be
210 // analyzed (in Angstrom). Sampling is the sampling rate in A/px, and step,
211 // is the resolution step for which analyze the local resolution.
212 void Monogenic::resolution2eval(int &count_res, double step,
213  double &resolution, double &last_resolution,
214  double &freq, double &freqL,
215  int &last_fourier_idx,
216  int &volsize,
217  bool &continueIter, bool &breakIter,
218  double &sampling, double &maxRes)
219 {
220 //TODO: simplify this function
221  resolution = maxRes - count_res*step;
222 
223  freq = sampling/resolution;
224  ++count_res;
225 
226  double Nyquist = 2*sampling;
227  double aux_frequency;
228  int fourier_idx;
229 
230  DIGFREQ2FFT_IDX(freq, volsize, fourier_idx);
231 
232  FFT_IDX2DIGFREQ(fourier_idx, volsize, aux_frequency);
233 
234  freq = aux_frequency;
235 
236  if (fourier_idx == last_fourier_idx)
237  {
238  continueIter = true;
239  return;
240  }
241 
242  last_fourier_idx = fourier_idx;
243  resolution = sampling/aux_frequency;
244 
245 
246  if (count_res == 0){
247  last_resolution = resolution;
248  }
249 
250  if (resolution<Nyquist)// || (resolution > last_resolution) )
251  {
252  breakIter = true;
253  return;
254  }
255 
256  freqL = sampling/(resolution + step);
257 
258  int fourier_idx_2;
259 
260  DIGFREQ2FFT_IDX(freqL, volsize, fourier_idx_2);
261 
262  if (fourier_idx_2 == fourier_idx)
263  {
264  if (fourier_idx > 0){
265  FFT_IDX2DIGFREQ(fourier_idx - 1, volsize, freqL);
266  }
267  else{
268  freqL = sampling/(resolution + step);
269  }
270  }
271 
272 }
273 
274 
275 // AMPLITUDEMONOSIG3D_LPF: Estimates the monogenic amplitude of a HPF map, myfftV is the
276 // Fourier transform of that map. The monogenic amplitude is "amplitude", and the
277 // parameters "fftVRiesz", "fftVRiesz_aux", "VRiesz", are auxiliar variables that will
278 // be defined inside the function (they are input to speed up monores algorithm).
279 // Freq, freqL and freqH, are the frequency of the HPF and the tails of a raise cosine.
280 // Note that once the monogenic amplitude is estimated, it is low pass filtered to obtain
281 // a smooth version and avoid rippling. freq_fourier_x, freq_fourier_y, freq_fourier_z,
282 // are the accesible Fourier frequencies along each axis.
283 void Monogenic::amplitudeMonoSig3D_LPF(const MultidimArray< std::complex<double> > &myfftV,
284  FourierTransformer &transformer_inv,
285  MultidimArray< std::complex<double> > &fftVRiesz,
286  MultidimArray< std::complex<double> > &fftVRiesz_aux, MultidimArray<double> &VRiesz,
287  double freq, double freqH, double freqL, MultidimArray<double> &iu,
288  Matrix1D<double> &freq_fourier_x, Matrix1D<double> &freq_fourier_y,
289  Matrix1D<double> &freq_fourier_z, MultidimArray<double> &amplitude,
290  int count, FileName fnDebug)
291 {
292 //FIXME: use atf.h
293 // FourierTransformer transformer_inv;
294 
295  fftVRiesz.initZeros(myfftV);
296  fftVRiesz_aux.initZeros(myfftV);
297  std::complex<double> J(0,1);
298 
299  // Filter the input volume and add it to amplitude
300  long n=0;
301  double ideltal=PI/(freq-freqH);
302 
303  for(size_t k=0; k<ZSIZE(myfftV); ++k)
304  {
305  for(size_t i=0; i<YSIZE(myfftV); ++i)
306  {
307  for(size_t j=0; j<XSIZE(myfftV); ++j)
308  {
309  double iun=DIRECT_MULTIDIM_ELEM(iu,n);
310  double un=1.0/iun;
311  if (freqH<=un && un<=freq)
312  {
313  DIRECT_MULTIDIM_ELEM(fftVRiesz, n) = DIRECT_MULTIDIM_ELEM(myfftV, n);
314  DIRECT_MULTIDIM_ELEM(fftVRiesz, n) *= 0.5*(1+cos((un-freq)*ideltal));//H;
315  DIRECT_MULTIDIM_ELEM(fftVRiesz_aux, n) = -J;
316  DIRECT_MULTIDIM_ELEM(fftVRiesz_aux, n) *= DIRECT_MULTIDIM_ELEM(fftVRiesz, n);
317  DIRECT_MULTIDIM_ELEM(fftVRiesz_aux, n) *= iun;
318  } else if (un>freq)
319  {
320  DIRECT_MULTIDIM_ELEM(fftVRiesz, n) = DIRECT_MULTIDIM_ELEM(myfftV, n);
321  DIRECT_MULTIDIM_ELEM(fftVRiesz_aux, n) = -J;
322  DIRECT_MULTIDIM_ELEM(fftVRiesz_aux, n) *= DIRECT_MULTIDIM_ELEM(fftVRiesz, n);
323  DIRECT_MULTIDIM_ELEM(fftVRiesz_aux, n) *= iun;
324  }
325  ++n;
326  }
327  }
328  }
329 
330  transformer_inv.inverseFourierTransform(fftVRiesz, amplitude);
332  DIRECT_MULTIDIM_ELEM(amplitude,n) *= DIRECT_MULTIDIM_ELEM(amplitude,n);
333 
334  //TODO: create a macro with these kind of code
335  // Calculate first component of Riesz vector
336  double ux;
337  n=0;
338  for(size_t k=0; k<ZSIZE(myfftV); ++k)
339  {
340  for(size_t i=0; i<YSIZE(myfftV); ++i)
341  {
342  for(size_t j=0; j<XSIZE(myfftV); ++j)
343  {
344  ux = VEC_ELEM(freq_fourier_x,j);
345  DIRECT_MULTIDIM_ELEM(fftVRiesz, n) = ux*DIRECT_MULTIDIM_ELEM(fftVRiesz_aux, n);
346  ++n;
347  }
348  }
349  }
350 
351  transformer_inv.inverseFourierTransform(fftVRiesz, VRiesz);
353  DIRECT_MULTIDIM_ELEM(amplitude,n)+=DIRECT_MULTIDIM_ELEM(VRiesz,n)*DIRECT_MULTIDIM_ELEM(VRiesz,n);
354 
355 
356  // Calculate second and third component of Riesz vector
357  n=0;
358  double uy;
359  double uz;
360  for(size_t k=0; k<ZSIZE(myfftV); ++k)
361  {
362  uz = VEC_ELEM(freq_fourier_z,k);
363  for(size_t i=0; i<YSIZE(myfftV); ++i)
364  {
365  uy = VEC_ELEM(freq_fourier_y,i);
366  for(size_t j=0; j<XSIZE(myfftV); ++j)
367  {
368  DIRECT_MULTIDIM_ELEM(fftVRiesz, n) = uz*DIRECT_MULTIDIM_ELEM(fftVRiesz_aux, n);
369  DIRECT_MULTIDIM_ELEM(fftVRiesz_aux, n) = uy*DIRECT_MULTIDIM_ELEM(fftVRiesz_aux, n);
370  ++n;
371  }
372  }
373  }
374 
375  transformer_inv.inverseFourierTransform(fftVRiesz, VRiesz);
376 
378  DIRECT_MULTIDIM_ELEM(amplitude,n) += DIRECT_MULTIDIM_ELEM(VRiesz,n)*DIRECT_MULTIDIM_ELEM(VRiesz,n);
379 
380  transformer_inv.inverseFourierTransform(fftVRiesz_aux, VRiesz);
381 
383  {
384  DIRECT_MULTIDIM_ELEM(amplitude,n)+=DIRECT_MULTIDIM_ELEM(VRiesz,n)*DIRECT_MULTIDIM_ELEM(VRiesz,n);
385  DIRECT_MULTIDIM_ELEM(amplitude,n)=sqrt(DIRECT_MULTIDIM_ELEM(amplitude,n));
386  }
387 
388  transformer_inv.FourierTransform(amplitude, fftVRiesz, false);
389 
390  double raised_w = PI/(freqL-freq);
391  n=0;
393  {
394  double un=1.0/DIRECT_MULTIDIM_ELEM(iu,n);
395  if (freqL>=un && un>=freq)
396  {
397  DIRECT_MULTIDIM_ELEM(fftVRiesz,n) *= 0.5*(1 + cos(raised_w*(un-freq)));
398  }
399  else
400  {
401  if (un>freqL)
402  {
403  DIRECT_MULTIDIM_ELEM(fftVRiesz,n) = 0;
404  }
405  }
406  }
407 
408  transformer_inv.inverseFourierTransform();
409 //
410 // saveImg = amplitude;
411 // FileName iternumber;
412 // iternumber = formatString("_Amplitude_new_%i.vol", count);
413 // saveImg.write(fnDebug+iternumber);
414 // saveImg.clear();
415 }
416 
417 
418 // STATISTICSINBINARYMASK2: Estimates the staticstics of two maps:
419 // Signal map "volS" and Noise map "volN". The signal statistics
420 // are obtained by mean of a binary mask. The results are the mean
421 // and variance of noise and signal, as well as the number of voxels
422 // of signal and noise NS and NN respectively. The thr95 represents
423 // the percentile 95 of noise distribution.
425  const MultidimArray<double> &volN,
426  MultidimArray<int> &mask, double &meanS, double &sdS2,
427  double &meanN, double &sdN2, double &significance, double &thr95, double &NS, double &NN)
428 {
429  double sumS = 0;
430  double sumS2 = 0;
431  double sumN = 0;
432  double sumN2 = 0;
433  NN = 0;
434  NS = 0;
435  std::vector<double> noiseValues;
436 
438  {
439  if (DIRECT_MULTIDIM_ELEM(mask, n)>0)
440  {
441  double amplitudeValue=DIRECT_MULTIDIM_ELEM(volS, n);
442  sumS += amplitudeValue;
443  sumS2 += amplitudeValue*amplitudeValue;
444  ++NS;
445  }
446  if (DIRECT_MULTIDIM_ELEM(mask, n)>=0) //BE CAREFULL WITH THE =
447  {
448  double amplitudeValueN=DIRECT_MULTIDIM_ELEM(volN, n);
449  noiseValues.push_back(amplitudeValueN);
450  sumN += amplitudeValueN;
451  sumN2 += amplitudeValueN*amplitudeValueN;
452  ++NN;
453  }
454  }
455 
456  std::sort(noiseValues.begin(),noiseValues.end());
457  thr95 = noiseValues[size_t(noiseValues.size()*significance)];
458  meanS = sumS/NS;
459  meanN = sumN/NN;
460  sdS2 = sumS2/NS - meanS*meanS;
461  sdN2 = sumN2/NN - meanN*meanN;
462 }
463 
464 
465 // STATISTICSINOUTBINARYMASK2: Estimates the staticstics of a single
466 // map. The signal statistics are obtained by mean of a binary mask.
467 // The results are the mean and variance of noise and signal, as well
468 // as the number of voxels of signal and noise NS and NN respectively.
469 // The thr95 represents the percentile 95 of noise distribution.
471  MultidimArray<int> &mask, double &meanS, double &sdS2,
472  double &meanN, double &sdN2, double &significance, double &thr95, double &NS, double &NN)
473 {
474  double sumS = 0;
475  double sumS2 = 0;
476  double sumN = 0;
477  double sumN2 = 0;
478  NN = 0;
479  NS = 0;
480 
481  std::vector<double> noiseValues;
482 
484  {
485  if (DIRECT_MULTIDIM_ELEM(mask, n)>=1)
486  {
487  double amplitudeValue=DIRECT_MULTIDIM_ELEM(volS, n);
488  sumS += amplitudeValue;
489  sumS2 += amplitudeValue*amplitudeValue;
490  ++NS;
491  }
492  if (DIRECT_MULTIDIM_ELEM(mask, n)==0)
493  {
494  double amplitudeValueN=DIRECT_MULTIDIM_ELEM(volS, n);
495  noiseValues.push_back(amplitudeValueN);
496  sumN += amplitudeValueN;
497  sumN2 += amplitudeValueN*amplitudeValueN;
498  ++NN;
499  }
500  }
501 
502  std::sort(noiseValues.begin(),noiseValues.end());
503  thr95 = noiseValues[size_t(noiseValues.size()*significance)];
504  meanS = sumS/NS;
505  meanN = sumN/NN;
506  sdS2 = sumS2/NS - meanS*meanS;
507  sdN2 = sumN2/NN - meanN*meanN;
508 }
509 
510 
511 // SETLOCALRESOLUTIONHALFMAPS: Set the local resolution of a voxel, by
512 // determining if the monogenic amplitude "amplitudeMS" is higher than
513 // the threshold of noise "thresholdNoise". Thus the local resolution
514 // map "plocalResolution" is set, with the resolution value "resolution"
515 // or with "resolution_2". "resolution" is the resolution for with
516 // the hypohtesis test is carried out, and "resolution_2" is the resolution
517 // of the analisys two loops ago (see monores method)
519  MultidimArray<int> &pMask, MultidimArray<double> &plocalResolutionMap,
520  double thresholdNoise, double resolution, double resolution_2)
521  {
523  {
524  if (DIRECT_MULTIDIM_ELEM(pMask, n)>=1)
525  if (DIRECT_MULTIDIM_ELEM(amplitudeMS, n)>thresholdNoise)
526  {
527  DIRECT_MULTIDIM_ELEM(pMask, n) = 1;
528  DIRECT_MULTIDIM_ELEM(plocalResolutionMap, n) = resolution;
529  }
530  else{
531  DIRECT_MULTIDIM_ELEM(pMask, n) += 1;
532  if (DIRECT_MULTIDIM_ELEM(pMask, n) >2)
533  {
534  DIRECT_MULTIDIM_ELEM(pMask, n) = 0;
535  DIRECT_MULTIDIM_ELEM(plocalResolutionMap, n) = resolution_2;
536  }
537  }
538  }
539  }
540 
541 // SETLOCALRESOLUTION: Set the local resolution of a voxel, by
542 // determining if the monogenic amplitude "amplitudeMS" is higher than
543 // the threshold of noise "thresholdNoise". Thus the local resolution
544 // map "plocalResolution" is set, with the resolution value "resolution"
545 // or with "resolution_2". "resolution" is the resolution for with
546 // the hypohtesis test is carried out, and "resolution_2" is the resolution
547 // of the analisys two loops ago (see monores method)
549  MultidimArray<int> &pMask, MultidimArray<double> &plocalResolutionMap,
550  double thresholdNoise, double resolution, double resolution_2)
551  {
553  {
554  if (DIRECT_MULTIDIM_ELEM(pMask, n)>=1)
555  if (DIRECT_MULTIDIM_ELEM(amplitudeMS, n)>thresholdNoise)
556  {
557  DIRECT_MULTIDIM_ELEM(pMask, n) = 1;
558  DIRECT_MULTIDIM_ELEM(plocalResolutionMap, n) = resolution;//sampling/freq;
559  }
560  else{
561  DIRECT_MULTIDIM_ELEM(pMask, n) += 1;
562  if (DIRECT_MULTIDIM_ELEM(pMask, n) >2)
563  {
564  DIRECT_MULTIDIM_ELEM(pMask, n) = -1;
565  DIRECT_MULTIDIM_ELEM(plocalResolutionMap, n) = resolution_2;//maxRes - counter*R_;
566  }
567  }
568  }
569  }
570 
571 
572 // MONOGENICAMPLITUDE_3D_FOURIER: Given the fourier transform of a map
573 // "myfftV", this function computes the monogenic amplitude "amplitude"
574 // iu is the inverse of the frequency in Fourier space.
575 void Monogenic::monogenicAmplitude_3D_Fourier(const MultidimArray< std::complex<double> > &myfftV,
576  MultidimArray<double> &iu, MultidimArray<double> &amplitude, int numberOfThreads)
577 {
578  Matrix1D<double> freq_fourier_z;
579  Matrix1D<double> freq_fourier_y;
580  Matrix1D<double> freq_fourier_x;
581 
582  iu = fourierFreqs_3D(myfftV, amplitude, freq_fourier_x, freq_fourier_y, freq_fourier_z);
583 
584  // Filter the input volume and add it to amplitude
586  MultidimArray< std::complex<double> > fftVRiesz_aux;
587  fftVRiesz.initZeros(myfftV);
588  fftVRiesz_aux.initZeros(myfftV);
589  std::complex<double> J(0,1);
590 
591  long n=0;
593  {
594  //double H=0.5*(1+cos((un-w1)*ideltal));
595  DIRECT_MULTIDIM_ELEM(fftVRiesz, n) = DIRECT_MULTIDIM_ELEM(myfftV, n);
596  DIRECT_MULTIDIM_ELEM(fftVRiesz_aux, n) = -J;
597  DIRECT_MULTIDIM_ELEM(fftVRiesz_aux, n) *= DIRECT_MULTIDIM_ELEM(fftVRiesz, n);
598  DIRECT_MULTIDIM_ELEM(fftVRiesz_aux, n) *= DIRECT_MULTIDIM_ELEM(iu, n);
599 
600  }
601  MultidimArray<double> VRiesz;
602  VRiesz.resizeNoCopy(amplitude);
603 
604  FourierTransformer transformer_inv;
605  transformer_inv.setThreadsNumber(numberOfThreads);
606  transformer_inv.inverseFourierTransform(fftVRiesz, VRiesz);
607 
609  DIRECT_MULTIDIM_ELEM(amplitude,n) = DIRECT_MULTIDIM_ELEM(VRiesz,n)*DIRECT_MULTIDIM_ELEM(VRiesz,n);
610 
611  // Calculate first component of Riesz vector
612  double uz;
613  double uy;
614  double ux;
615  n=0;
616  for(size_t k=0; k<ZSIZE(myfftV); ++k)
617  {
618  for(size_t i=0; i<YSIZE(myfftV); ++i)
619  {
620  for(size_t j=0; j<XSIZE(myfftV); ++j)
621  {
622  ux = VEC_ELEM(freq_fourier_x,j);
623  DIRECT_MULTIDIM_ELEM(fftVRiesz, n) = ux*DIRECT_MULTIDIM_ELEM(fftVRiesz_aux, n);
624  ++n;
625  }
626  }
627  }
628 
629  transformer_inv.inverseFourierTransform(fftVRiesz, VRiesz);
631  DIRECT_MULTIDIM_ELEM(amplitude,n) += DIRECT_MULTIDIM_ELEM(VRiesz,n)*DIRECT_MULTIDIM_ELEM(VRiesz,n);
632 
633  // Calculate second and third components of Riesz vector
634  n=0;
635  for(size_t k=0; k<ZSIZE(myfftV); ++k)
636  {
637  uz = VEC_ELEM(freq_fourier_z,k);
638  for(size_t i=0; i<YSIZE(myfftV); ++i)
639  {
640  uy = VEC_ELEM(freq_fourier_y,i);
641  for(size_t j=0; j<XSIZE(myfftV); ++j)
642  {
643  DIRECT_MULTIDIM_ELEM(fftVRiesz, n) = uy*DIRECT_MULTIDIM_ELEM(fftVRiesz_aux, n);
644  DIRECT_MULTIDIM_ELEM(fftVRiesz_aux, n) = uz*DIRECT_MULTIDIM_ELEM(fftVRiesz_aux, n);
645  ++n;
646  }
647  }
648  }
649  transformer_inv.inverseFourierTransform(fftVRiesz, VRiesz);
650 
652  DIRECT_MULTIDIM_ELEM(amplitude,n)+=DIRECT_MULTIDIM_ELEM(VRiesz,n)*DIRECT_MULTIDIM_ELEM(VRiesz,n);
653 
654  transformer_inv.inverseFourierTransform(fftVRiesz_aux, VRiesz);
655 
657  {
658  DIRECT_MULTIDIM_ELEM(amplitude,n) += DIRECT_MULTIDIM_ELEM(VRiesz,n)*DIRECT_MULTIDIM_ELEM(VRiesz,n);
659  DIRECT_MULTIDIM_ELEM(amplitude,n) = sqrt(DIRECT_MULTIDIM_ELEM(amplitude,n));
660  }
661 }
662 
663 
664 //ADDNOISE: This function add gaussian with mean = double mean and standard deviation
665 // equal to double stddev to a map given by "vol"
666 void Monogenic::addNoise(MultidimArray<double> &vol, double mean, double stddev)
667 {
668 
669  std::random_device rd;
670  std::default_random_engine generator(rd());
671  std::normal_distribution<double> dist(mean, stddev);
672 
674  DIRECT_MULTIDIM_ELEM(vol,n) += dist(generator);
675 }
676 
677 
678 //CREATEDATATEST: This function generates fringe pattern (rings) map returned
679 // as a multidimArray, with dimensions given by xdim, ydim and zdim. The
680 // wavelength of the pattern is given by double wavelength
681 MultidimArray<double> Monogenic::createDataTest(size_t xdim, size_t ydim, size_t zdim,
682  double wavelength)
683 {
684  int siz_z;
685  int siz_y;
686  int siz_x;
687  double x;
688  double y;
689  double z;
690 
691  siz_z = xdim/2;
692  siz_y = ydim/2;
693  siz_x = xdim/2;
694  MultidimArray<double> testmap;
695  testmap.initZeros(zdim, ydim, xdim);
696 
697  long n=0;
698  for(int k=0; k<zdim; ++k)
699  {
700  z = (k - siz_z);
701  z= z*z;
702  for(int i=0; i<ydim; ++i)
703  {
704  y = (i - siz_y);
705  y = y*y;
706  y = z + y;
707  for(int j=0; j<xdim; ++j)
708  {
709  x = (j - siz_x);
710  x = x*x;
711  x = sqrt(x + y);
712  DIRECT_MULTIDIM_ELEM(testmap, n) = cos(2*PI/wavelength*x);
713  ++n;
714  }
715  }
716  }
717 
718  FileName fn;
719  fn = formatString("fringes.vol");
720  Image<double> saveImg;
721  saveImg() = testmap;
722  saveImg.write(fn);
723 
724  return testmap;
725 }
726 
#define YSIZE(v)
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
void inverseFourierTransform()
Definition: xmipp_fftw.cpp:329
void setThreadsNumber(int tNumber)
Definition: xmipp_fftw.h:119
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)
double icdf_gauss(double p)
void statisticsInOutBinaryMask2(const MultidimArray< double > &volS, MultidimArray< int > &mask, double &meanS, double &sdS2, double &meanN, double &sdN2, double &significance, double &thr95, double &NS, double &NN)
void findCliffValue(MultidimArray< double > &inputmap, int &radius, int &radiuslimit, MultidimArray< int > &mask, double rsmooth)
void statisticsInBinaryMask2(const MultidimArray< double > &volS, const MultidimArray< double > &volN, MultidimArray< int > &mask, double &meanS, double &sdS2, double &meanN, double &sdN2, double &significance, double &thr95, double &NS, double &NN)
void resolution2eval(int &count_res, double step, double &resolution, double &last_resolution, double &freq, double &freqL, int &last_fourier_idx, int &volsize, bool &continueIter, bool &breakIter, double &sampling, double &maxRes)
#define DIGFREQ2FFT_IDX(freq, size, idx)
Definition: xmipp_fft.h:61
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 A3D_ELEM(V, k, i, j)
#define FOR_ALL_ELEMENTS_IN_ARRAY3D(V)
void setLocalResolutionHalfMaps(const MultidimArray< double > &amplitudeMS, MultidimArray< int > &pMask, MultidimArray< double > &plocalResolutionMap, double thresholdNoise, double resolution, double resolution_2)
#define sampling
#define XSIZE(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
MultidimArray< double > fourierFreqs_3D(const MultidimArray< std::complex< double > > &myfftV, const MultidimArray< double > &inputVol, Matrix1D< double > &freq_fourier_x, Matrix1D< double > &freq_fourier_y, Matrix1D< double > &freq_fourier_z)
#define ZSIZE(v)
Matrix1D< double > fourierFreqVector(size_t dimarrayFourier, size_t dimarrayReal)
double z
#define DIRECT_MULTIDIM_ELEM(v, n)
void initZeros()
Definition: matrix1d.h:592
void sort(struct DCEL_T *dcel)
Definition: sorting.cpp:18
void amplitudeMonoSig3D_LPF(const MultidimArray< std::complex< double > > &myfftV, FourierTransformer &transformer_inv, MultidimArray< std::complex< double > > &fftVRiesz, MultidimArray< std::complex< double > > &fftVRiesz_aux, MultidimArray< double > &VRiesz, double freq, double freqH, double freqL, MultidimArray< double > &iu, Matrix1D< double > &freq_fourier_x, Matrix1D< double > &freq_fourier_y, Matrix1D< double > &freq_fourier_z, 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)
void monogenicAmplitude_3D_Fourier(const MultidimArray< std::complex< double > > &myfftV, MultidimArray< double > &iu, MultidimArray< double > &amplitude, int numberOfThreads)
#define j
void proteinRadiusVolumeAndShellStatistics(const MultidimArray< int > &mask, int &radius, long &vol)
MultidimArray< double > createDataTest(size_t xdim, size_t ydim, size_t zdim, double wavelength)
String formatString(const char *format,...)
doublereal * u
void setLocalResolutionMap(const MultidimArray< double > &amplitudeMS, MultidimArray< int > &pMask, MultidimArray< double > &plocalResolutionMap, double thresholdNoise, double resolution, double resolution_2)
void initZeros(const MultidimArray< T1 > &op)
void addNoise(MultidimArray< double > &vol, double mean, double stddev)
#define PI
Definition: tools.h:43
int * n