Xmipp  v3.23.11-Nereus
xmipp_fftw.h
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Roberto Marabini (roberto@cnb.csic.es)
4  * Carlos Oscar S. Sorzano (coss@cnb.csic.es)
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 #ifndef _CORE__XmippFFTW_H
28 #define _CORE__XmippFFTW_H
29 
30 #include <complex>
31 #include "fftw3.h"
32 #include "multidim_array.h"
33 #include "multidim_array_generic.h"
34 #include "xmipp_fft.h"
35 
36 
61 {
62 public:
65 
68 
71 
72  /* fftw Forawrd plan */
73  fftw_plan fPlanForward;
74 
75  /* fftw Backward plan */
76  fftw_plan fPlanBackward;
77 
78  /* number of threads*/
79  int nthreads;
80 
81  /* Threads has been used in this program*/
83 
84  /* Sign where the normalization is applied */
85  int normSign;
86 
87  // Public methods
88 public:
91 
93  FourierTransformer(const FourierTransformer& fTransform);
94 
96  FourierTransformer(int _normSign);
97 
100 
103 
119  void setThreadsNumber(int tNumber)
120  {
121  if (tNumber!=1)
122  {
123  threadsSetOn=true;
124  nthreads = tNumber;
125  if(fftw_init_threads()==0)
126  REPORT_ERROR(ERR_THREADS_NOTINIT, (std::string)"FFTW cannot init threads (setThreadsNumber)");
127  fftw_plan_with_nthreads(nthreads);
128  }
129  }
142  void changeThreadsNumber(int tNumber)
143  {
144  nthreads = tNumber;
145  fftw_plan_with_nthreads(nthreads);
146  }
147 
150  void destroyThreads(void )
151  {
152  nthreads = 1;
153  if(threadsSetOn)
154  fftw_cleanup_threads();
155 
156  threadsSetOn=false;
157  }
158 
165  template <typename T, typename T1>
166  void FourierTransform(T& v, T1& V, bool getCopy=true)
167  {
168  setReal(v);
169  Transform(FFTW_FORWARD);
170  if (getCopy)
171  getFourierCopy(V);
172  else
173  getFourierAlias(V);
174  }
175 
179  void FourierTransform();
180 
185 
191 
197  template <typename T, typename T1>
198  void inverseFourierTransform(T& V, T1& v)
199  {
200  setReal(v);
201  setFourier(V);
202  Transform(FFTW_BACKWARD);
203  }
204 
206  template <typename T>
207  void getFourierAlias(T& V)
208  {
209  V.alias(fFourier);
210  return;
211  }
212 
214  template <typename T>
215  void setFourierAlias(T& V)
216  {
217  fFourier.alias(V);
218  return;
219  }
220 
222  template <typename T>
223  void getFourierCopy(T& V)
224  {
225  V.resizeNoCopy(fFourier);
226  memcpy(MULTIDIM_ARRAY(V),MULTIDIM_ARRAY(fFourier),
227  MULTIDIM_SIZE(fFourier)*2*sizeof(double));
228  }
229 
230 
233  template <typename T>
235  {
236  V.resizeNoCopy(*fReal);
237  int ndim=3;
238  if (ZSIZE(*fReal)==1)
239  {
240  ndim=2;
241  if (YSIZE(*fReal)==1)
242  ndim=1;
243  }
244  double *ptrSource=NULL;
245  double *ptrDest=NULL;
246  switch (ndim)
247  {
248  case 1:
250  {
251  ptrDest=(double*)&DIRECT_A1D_ELEM(V,i);
252  if (i<XSIZE(fFourier))
253  {
254  ptrSource=(double*)&DIRECT_A1D_ELEM(fFourier,i);
255  *ptrDest=*ptrSource;
256  *(ptrDest+1)=*(ptrSource+1);
257  }
258  else
259  {
260  ptrSource=(double*)&DIRECT_A1D_ELEM(fFourier,XSIZE(*fReal)-i);
261  *ptrDest=*ptrSource;
262  *(ptrDest+1)=-(*(ptrSource+1));
263  }
264  }
265  break;
266  case 2:
268  {
269  ptrDest=(double*)&DIRECT_A2D_ELEM(V,i,j);
270  if (j<XSIZE(fFourier))
271  {
272  ptrSource=(double*)&DIRECT_A2D_ELEM(fFourier,i,j);
273  *ptrDest=*ptrSource;
274  *(ptrDest+1)=*(ptrSource+1);
275  }
276  else
277  {
278  ptrSource=(double*)&DIRECT_A2D_ELEM(fFourier,
279  (YSIZE(*fReal)-i)%YSIZE(*fReal),
280  XSIZE(*fReal)-j);
281  *ptrDest=*ptrSource;
282  *(ptrDest+1)=-(*(ptrSource+1));
283  }
284  }
285  break;
286  case 3:
288  {
289  ptrDest=(double*)&DIRECT_A3D_ELEM(V,k,i,j);
290  if (j<XSIZE(fFourier))
291  {
292  ptrSource=(double*)&DIRECT_A3D_ELEM(fFourier,k,i,j);
293  *ptrDest=*ptrSource;
294  *(ptrDest+1)=*(ptrSource+1);
295  }
296  else
297  {
298  ptrSource=(double*)&DIRECT_A3D_ELEM(fFourier,
299  (ZSIZE(*fReal)-k)%ZSIZE(*fReal),
300  (YSIZE(*fReal)-i)%YSIZE(*fReal),
301  XSIZE(*fReal)-j);
302  *ptrDest=*ptrSource;
303  *(ptrDest+1)=-(*(ptrSource+1));
304  }
305  }
306  break;
307  }
308  }
309 
310 
314  template <typename T, typename T1>
315  void completeFourierTransform(T& v, T1& V)
316  {
317  setReal(v);
318  Transform(FFTW_FORWARD);
320  }
321 
325  template <typename T>
327  {
328  int ndim=3;
329  if (ZSIZE(*fReal)==1)
330  {
331  ndim=2;
332  if (YSIZE(*fReal)==1)
333  ndim=1;
334  }
335  switch (ndim)
336  {
337  case 1:
339  DIRECT_A1D_ELEM(fFourier,i)=DIRECT_A1D_ELEM(V,i);
340  break;
341  case 2:
343  DIRECT_A2D_ELEM(fFourier,i,j) = DIRECT_A2D_ELEM(V,i,j);
344  break;
345  case 3:
347  DIRECT_A3D_ELEM(fFourier,k,i,j) = DIRECT_A3D_ELEM(V,k,i,j);
348  break;
349  }
350  }
351 
352  // Internal methods
353 public:
354  /* Pointer to the array of doubles with which the plan was computed */
355  double * dataPtr;
356 
357  /* Pointer to the array of complex<double> with which the plan was computed */
358  std::complex<double> * complexDataPtr;
359 
360  /* Init object*/
361  void init();
363  void clear();
370  void cleanup(void)
371  {
372  fftw_cleanup();
373  }
374 
378  void recomputePlanR2C();
379 
386  void Transform(int sign);
387 
389  const MultidimArray<double> &getReal() const;
391 
397  void setReal(MultidimArray<double> &img);
398 
404  void setReal(MultidimArray<std::complex<double> > &img);
405 
411  void setFourier(const MultidimArray<std::complex<double> > &imgFourier);
412 
413  /* Set normalization sign.
414  * It defines when the normalization must be applied, when doing
415  * FFTW_FORWARD OR FFTW_BACKWARD. By default, FFTW_FORWARD.*/
416  void setNormalizationSign(int _normSign)
417  {
418  normSign = _normSign;
419  }
420 
421 };
422 
426 void FFT_magnitude(const MultidimArray< std::complex< double > > & v,
428 
432 void FFT_phase(const MultidimArray< std::complex< double > > & v,
433  MultidimArray< double >& phase);
434 
442 void radial_magnitude(const MultidimArray<double> & v, MultidimArray< std::complex< double > > &V,
443  MultidimArray< double >& radialMagnitude);
444 
451 template <typename T>
453 {
454  Img.checkDimension(1);
455 
456  // Compute the Fourier Transform
458  FourierTransformer transformer1;
459  R=Img;
460  transformer1.FourierTransform(R, FFT1, false);
461 
462  // Multiply FFT1 * FFT1'
463  double dSize=XSIZE(Img);
465  {
466  double *ptr=(double*)&DIRECT_MULTIDIM_ELEM(FFT1,n);
467  double &realPart=*ptr;
468  double &imagPart=*(ptr+1);
469  realPart=dSize*(realPart*realPart+imagPart*imagPart);
470  imagPart=0;
471  }
472 
473  // Invert the product, in order to obtain the correlation image
474  transformer1.inverseFourierTransform();
475 
476  // Center the resulting image to obtain a centered autocorrelation
477  CenterFFT(R, true);
478 }
479 
487 template <typename T>
489  const MultidimArray< T > & m2,
491 {
492  m1.checkDimension(2);
493  m2.checkDimension(2);
494 
495  // Compute the Fourier Transforms
497  FourierTransformer transformer1, transformer2;
498  R=m1;
499  transformer1.FourierTransform(R, FFT1, false);
500  transformer2.FourierTransform((MultidimArray<T> &)m2, FFT2, false);
501 
502  // Multiply FFT1 * FFT2'
503  double dSize=XSIZE(m1);
505  FFT1(i) *= dSize * conj(FFT2(i));
506 
507  // Invert the product, in order to obtain the correlation image
508  transformer1.inverseFourierTransform();
509 
510  // Center the resulting image to obtain a centered autocorrelation
511  CenterFFT(R, true);
512 }
513 
521 void fast_correlation_vector(const MultidimArray< std::complex<double> > & FFT1,
522  const MultidimArray< std::complex<double> > & FFT2,
524  FourierTransformer &transformer);
525 
533 template <class T>
535  MultidimArray<T> &result)
536 {
537  v1.checkDimension(1);
538  v2.checkDimension(1);
539 
540  result.initZeros(v1);
541  result.setXmippOrigin();
542  int N=XSIZE(v1)-1;
544  for (int k=0; k<XSIZE(v1); ++k)
545  A1D_ELEM(result,i)+=DIRECT_A1D_ELEM(v1,intWRAP(k+i,0,N))*
546  DIRECT_A1D_ELEM(v2,k);
547  STARTINGX(result)=0;
548 }
549 
552 {
553 public:
556 };
557 
567  const MultidimArray<double> & m2,
569  CorrelationAux &aux,
570  bool center=true);
571 
572 void correlation_matrix(const MultidimArray< std::complex< double > > & FFT1,
573  const MultidimArray<double> & m2,
575  CorrelationAux &aux,
576  bool center=true);
577 
581 void correlation_matrix(const MultidimArray< std::complex< double > > & FFT1,
582  const MultidimArray< std::complex< double > > & FFT2,
584  CorrelationAux &aux,
585  bool center=true);
586 
593 template <typename T>
595 {
596  // Compute the Fourier Transform
598  FourierTransformer transformer1;
599  R=Img;
600  transformer1.FourierTransform(R, FFT1, false);
601 
602  // Multiply FFT1 * FFT1'
603  double dSize=MULTIDIM_SIZE(Img);
605  {
606  double *ptr=(double*)&DIRECT_MULTIDIM_ELEM(FFT1,n);
607  double &realPart=*ptr;
608  double &imagPart=*(ptr+1);
609  realPart=dSize*(realPart*realPart+imagPart*imagPart);
610  imagPart=0;
611  }
612 
613  // Invert the product, in order to obtain the correlation image
614  transformer1.inverseFourierTransform();
615 
616  // Center the resulting image to obtain a centered autocorrelation
617  CenterFFT(R, true);
618 }
619 
622 
624  const MultidimArray<double> &kernel,
625  MultidimArray<double> &result);
626 
628  MultidimArray<double> &kernel,
629  MultidimArray<double> &result);
630 
636  double sampling_rate,
639  MultidimArray< double >& frc_noise,
641  MultidimArray< double >& error_l2,
642  bool skipdpr=false,
643  bool doRfactor = false,
644  double minFreq = -1,
645  double maxFreq = 0.5,
646  double * rFactor= NULL);
647 
652 void scaleToSizeFourier(int Zdim, int Ydim, int Xdim, MultidimArray<double> &mdaIn, MultidimArray<double> &mdaOut, int nThreads=1);
653 
657 template<typename T>
659  MultidimArray<std::complex<T> > &inFourier, MultidimArray<std::complex<T> > &outFourier);
660 
661 void selfScaleToSizeFourier(int Zdim, int Ydim, int Xdim, MultidimArray<double> &mda, int nthreads=1);
662 
663 void selfScaleToSizeFourier(int Ydim, int Xdim, MultidimArray<double> &mda, int nthreads=1);
665 void selfScaleToSizeFourier(int Zdim, int Ydim, int Xdim, MultidimArrayGeneric &mda, int nthreads=1);
666 void selfScaleToSizeFourier(int Ydim, int Xdim, MultidimArrayGeneric &mda, int nthreads=1);
667 
668 #define POWER_SPECTRUM 0
669 #define AMPLITUDE_SPECTRUM 1
670 
676  MultidimArray<double> &spectrum,
677  int spectrum_type=AMPLITUDE_SPECTRUM);
678 
684  MultidimArray<double> &spectrum,
685  bool leave_origin_intact=false);
686 
692  MultidimArray<double> &spectrum,
693  bool leave_origin_intact=false);
694 
700  MultidimArray<double> &Mout,
701  int spectrum_type=AMPLITUDE_SPECTRUM,
702  bool leave_origin_intact=false);
703 
709  MultidimArray<double> &Mout,
710  const MultidimArray<double> &spectrum_ref,
711  int spectrum_type=AMPLITUDE_SPECTRUM,
712  bool leave_origin_intact=false);
713 
717 void randomizePhases(MultidimArray<double> &Min, double wRandom);
718 #endif
719 
#define YSIZE(v)
void FFT_phase(const MultidimArray< std::complex< double > > &v, MultidimArray< double > &phase)
Definition: xmipp_fftw.cpp:408
void adaptSpectrum(MultidimArray< double > &Min, MultidimArray< double > &Mout, const MultidimArray< double > &spectrum_ref, int spectrum_type=AMPLITUDE_SPECTRUM, bool leave_origin_intact=false)
Definition: xmipp_fftw.cpp:849
alglib::complex conj(const alglib::complex &z)
Definition: ap.cpp:4988
void inverseFourierTransform()
Definition: xmipp_fftw.cpp:329
void setThreadsNumber(int tNumber)
Definition: xmipp_fftw.h:119
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
void auto_correlation_matrix(const MultidimArray< T > &Img, MultidimArray< double > &R)
Definition: xmipp_fftw.h:594
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY2D(m)
double sign
#define MULTIDIM_SIZE(v)
MultidimArray< std::complex< double > > fFourier
Definition: xmipp_fftw.h:70
void inverseFourierTransform(T &V, T1 &v)
Definition: xmipp_fftw.h:198
void destroyThreads(void)
Definition: xmipp_fftw.h:150
void setFourierAlias(T &V)
Definition: xmipp_fftw.h:215
void cleanup(void)
Definition: xmipp_fftw.h:370
void setFromCompleteFourier(T &V)
Definition: xmipp_fftw.h:326
#define DIRECT_A2D_ELEM(v, i, j)
#define A1D_ELEM(v, i)
void correlation_matrix(const MultidimArray< double > &m1, const MultidimArray< double > &m2, MultidimArray< double > &R, CorrelationAux &aux, bool center=true)
Definition: xmipp_fftw.cpp:869
#define MULTIDIM_ARRAY(v)
void auto_correlation_vector(const MultidimArray< T > &Img, MultidimArray< double > &R)
Definition: xmipp_fftw.h:452
void frc_dpr(MultidimArray< double > &m1, MultidimArray< double > &m2, double sampling_rate, MultidimArray< double > &freq, MultidimArray< double > &frc, MultidimArray< double > &frc_noise, MultidimArray< double > &dpr, MultidimArray< double > &error_l2, bool skipdpr=false, bool doRfactor=false, double minFreq=-1, double maxFreq=0.5, double *rFactor=NULL)
Definition: xmipp_fftw.cpp:491
void correlation_vector(const MultidimArray< T > &m1, const MultidimArray< T > &m2, MultidimArray< double > &R)
Definition: xmipp_fftw.h:488
FourierTransformer & operator=(const FourierTransformer &other)
Definition: xmipp_fftw.cpp:65
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY3D(V)
void convolutionFFTStack(const MultidimArray< double > &img, const MultidimArray< double > &kernel, MultidimArray< double > &result)
Definition: xmipp_fftw.cpp:429
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY1D(v)
MultidimArray< std::complex< double > > * fComplex
Definition: xmipp_fftw.h:67
#define STARTINGX(v)
void setNormalizationSign(int _normSign)
Definition: xmipp_fftw.h:416
#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
MultidimArray< double > * fReal
Definition: xmipp_fftw.h:64
void getSpectrum(MultidimArray< double > &Min, MultidimArray< double > &spectrum, int spectrum_type=AMPLITUDE_SPECTRUM)
Definition: xmipp_fftw.cpp:752
void CenterFFT(MultidimArray< T > &v, bool forward)
Definition: xmipp_fft.h:291
const MultidimArray< double > & getReal() const
Definition: xmipp_fftw.cpp:118
#define DIRECT_A1D_ELEM(v, i)
double v1
void setReal(MultidimArray< double > &img)
Definition: xmipp_fftw.cpp:129
void Transform(int sign)
Definition: xmipp_fftw.cpp:256
void getCompleteFourier(T &V)
Definition: xmipp_fftw.h:234
void correlation_vector_no_Fourier(const MultidimArray< T > &v1, const MultidimArray< T > &v2, MultidimArray< T > &result)
Definition: xmipp_fftw.h:534
void setFourier(const MultidimArray< std::complex< double > > &imgFourier)
Definition: xmipp_fftw.cpp:249
fftw_plan fPlanBackward
Definition: xmipp_fftw.h:76
void multiplyBySpectrum(MultidimArray< double > &Min, MultidimArray< double > &spectrum, bool leave_origin_intact=false)
Definition: xmipp_fftw.cpp:806
#define XSIZE(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define ZSIZE(v)
void fast_correlation_vector(const MultidimArray< std::complex< double > > &FFT1, const MultidimArray< std::complex< double > > &FFT2, MultidimArray< double > &R, FourierTransformer &transformer)
Definition: xmipp_fftw.cpp:926
#define DIRECT_MULTIDIM_ELEM(v, n)
void selfScaleToSizeFourier(int Zdim, int Ydim, int Xdim, MultidimArray< double > &mda, int nthreads=1)
Definition: xmipp_fftw.cpp:723
void convolutionFFT(MultidimArray< double > &img, MultidimArray< double > &kernel, MultidimArray< double > &result)
Definition: xmipp_fftw.cpp:457
fftw_plan fPlanForward
Definition: xmipp_fftw.h:73
void scaleToSizeFourier(int Zdim, int Ydim, int Xdim, MultidimArray< double > &mdaIn, MultidimArray< double > &mdaOut, int nThreads=1)
Definition: xmipp_fftw.cpp:658
void alias(const MultidimArray< T > &m)
#define DIRECT_A3D_ELEM(v, k, i, j)
void FourierTransform(T &v, T1 &V, bool getCopy=true)
Definition: xmipp_fftw.h:166
std::complex< double > * complexDataPtr
Definition: xmipp_fftw.h:358
#define j
const MultidimArray< std::complex< double > > & getComplex() const
Definition: xmipp_fftw.cpp:123
Threads cannot be initiated.
Definition: xmipp_error.h:188
void randomizePhases(MultidimArray< double > &Min, double wRandom)
Definition: xmipp_fftw.cpp:981
#define FOR_ALL_ELEMENTS_IN_ARRAY1D(v)
void getFourierAlias(T &V)
Definition: xmipp_fftw.h:207
void changeThreadsNumber(int tNumber)
Definition: xmipp_fftw.h:142
void radial_magnitude(const MultidimArray< double > &v, MultidimArray< std::complex< double > > &V, MultidimArray< double > &radialMagnitude)
Definition: xmipp_fftw.cpp:416
void whitenSpectrum(MultidimArray< double > &Min, MultidimArray< double > &Mout, int spectrum_type=AMPLITUDE_SPECTRUM, bool leave_origin_intact=false)
Definition: xmipp_fftw.cpp:835
void completeFourierTransform(T &v, T1 &V)
Definition: xmipp_fftw.h:315
void getFourierCopy(T &V)
Definition: xmipp_fftw.h:223
MultidimArray< std::complex< double > > FFT2
Definition: xmipp_fftw.h:554
#define AMPLITUDE_SPECTRUM
Definition: xmipp_fftw.h:669
void initZeros(const MultidimArray< T1 > &op)
void enforceHermitianSymmetry()
Definition: xmipp_fftw.cpp:335
FourierTransformer transformer2
Definition: xmipp_fftw.h:555
void FFT_magnitude(const MultidimArray< std::complex< double > > &v, MultidimArray< double > &mag)
Definition: xmipp_fftw.cpp:393
int * n
void divideBySpectrum(MultidimArray< double > &Min, MultidimArray< double > &spectrum, bool leave_origin_intact=false)
Definition: xmipp_fftw.cpp:788
#define intWRAP(x, x0, xF)
Definition: xmipp_macros.h:272