Xmipp  v3.23.11-Nereus
Public Member Functions | Public Attributes | List of all members
FourierTransformer Class Reference

#include <xmipp_fftw.h>

Collaboration diagram for FourierTransformer:
Collaboration graph
[legend]

Public Member Functions

 FourierTransformer ()
 
 FourierTransformer (const FourierTransformer &fTransform)
 
 FourierTransformer (int _normSign)
 
FourierTransformeroperator= (const FourierTransformer &other)
 
 ~FourierTransformer ()
 
void setThreadsNumber (int tNumber)
 
void changeThreadsNumber (int tNumber)
 
void destroyThreads (void)
 
template<typename T , typename T1 >
void FourierTransform (T &v, T1 &V, bool getCopy=true)
 
void FourierTransform ()
 
void enforceHermitianSymmetry ()
 
void inverseFourierTransform ()
 
template<typename T , typename T1 >
void inverseFourierTransform (T &V, T1 &v)
 
template<typename T >
void getFourierAlias (T &V)
 
template<typename T >
void setFourierAlias (T &V)
 
template<typename T >
void getFourierCopy (T &V)
 
template<typename T >
void getCompleteFourier (T &V)
 
template<typename T , typename T1 >
void completeFourierTransform (T &v, T1 &V)
 
template<typename T >
void setFromCompleteFourier (T &V)
 
void init ()
 
void clear ()
 
void cleanup (void)
 
void recomputePlanR2C ()
 
void Transform (int sign)
 
const MultidimArray< double > & getReal () const
 
const MultidimArray< std::complex< double > > & getComplex () const
 
void setReal (MultidimArray< double > &img)
 
void setReal (MultidimArray< std::complex< double > > &img)
 
void setFourier (const MultidimArray< std::complex< double > > &imgFourier)
 
void setNormalizationSign (int _normSign)
 

Public Attributes

MultidimArray< double > * fReal
 
MultidimArray< std::complex< double > > * fComplex
 
MultidimArray< std::complex< double > > fFourier
 
fftw_plan fPlanForward
 
fftw_plan fPlanBackward
 
int nthreads
 
bool threadsSetOn
 
int normSign
 
double * dataPtr
 
std::complex< double > * complexDataPtr
 

Detailed Description

Fourier Transformer class.

The memory for the Fourier transform is handled by this object. However, the memory for the real space image is handled externally and this object only has a pointer to it.

Here you have an example of use

FourierTransformer transformer;
transformer.FourierTransform(V(),Vfft,false);
Vmag.resize(Vfft);
Vmag(k,i,j)=20*log10(abs(Vfft(k,i,j)));

Definition at line 60 of file xmipp_fftw.h.

Constructor & Destructor Documentation

◆ FourierTransformer() [1/3]

FourierTransformer::FourierTransformer ( )

Default constructor

Definition at line 38 of file xmipp_fftw.cpp.

39 {
40  init();
41  nthreads=1;
42  pthread_mutex_lock(&fftw_plan_mutex);
43  nInstances++;
44  pthread_mutex_unlock(&fftw_plan_mutex);
45  threadsSetOn=false;
46  normSign = FFTW_FORWARD;
47 }
int nInstances
Definition: xmipp_fftw.cpp:35

◆ FourierTransformer() [2/3]

FourierTransformer::FourierTransformer ( const FourierTransformer fTransform)

Copy constructor

Definition at line 60 of file xmipp_fftw.cpp.

61 {
62  REPORT_ERROR(ERR_UNCLASSIFIED,"Fourier transformers should not be copied");
63 }
Just to locate unclassified errors.
Definition: xmipp_error.h:192
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211

◆ FourierTransformer() [3/3]

FourierTransformer::FourierTransformer ( int  _normSign)

Constructor setting the sign of normalization application

Definition at line 49 of file xmipp_fftw.cpp.

50 {
51  init();
52  pthread_mutex_lock(&fftw_plan_mutex);
53  nInstances++;
54  pthread_mutex_unlock(&fftw_plan_mutex);
55  nthreads=1;
56  threadsSetOn=false;
57  normSign = _normSign;
58 }
int nInstances
Definition: xmipp_fftw.cpp:35

◆ ~FourierTransformer()

FourierTransformer::~FourierTransformer ( )

Destructor

Definition at line 93 of file xmipp_fftw.cpp.

94 {
95  clear();
96 
97  pthread_mutex_lock(&fftw_plan_mutex);
98  nInstances--;
99 
100  // Check if a plan was already created.
101  if (planCreated)
102  {
103  // Check if this is last instance of a FFT.
104  if (nInstances == 0)
105  {
106  destroyThreads();
107  planCreated = false;
108  // Don't call cleanup.
109  // There might be other transformers, and this call would
110  // invalidate it's plans
111 // cleanup();
112  }
113  }
114  pthread_mutex_unlock(&fftw_plan_mutex);
115 }
int nInstances
Definition: xmipp_fftw.cpp:35
bool planCreated
Definition: xmipp_fftw.cpp:34
void destroyThreads(void)
Definition: xmipp_fftw.h:150

Member Function Documentation

◆ changeThreadsNumber()

void FourierTransformer::changeThreadsNumber ( int  tNumber)
inline

Change Number of threads.

The nthreads argument indicates the number of threads you want FFTW to use (or actually, the maximum number). All plans subsequently created with any planner routine will use that many threads. You can call fftw_plan_with_nthreads, create some plans, call fftw_plan_with_nthreads again with a different argument, and create some more plans for a new number of threads. Plans already created before a call to fftw_plan_with_nthreads are unaffected. If you pass an nthreads argument of 1 (the default), threads are disabled for subsequent plans.

Definition at line 142 of file xmipp_fftw.h.

143  {
144  nthreads = tNumber;
145  fftw_plan_with_nthreads(nthreads);
146  }

◆ cleanup()

void FourierTransformer::cleanup ( void  )
inline

FFTW's planner saves some other persistent data, such as the accumulated wisdom and a list of algorithms available in the current configuration. If you want to deallocate all of that and reset FFTW to the pristine state it was in when you started your program, you can call:

Definition at line 370 of file xmipp_fftw.h.

371  {
372  fftw_cleanup();
373  }

◆ clear()

void FourierTransformer::clear ( )

Clear object

Definition at line 79 of file xmipp_fftw.cpp.

80 {
81  fFourier.clear();
82  // Anything to do with plans has to be protected for threads!
83  pthread_mutex_lock(&fftw_plan_mutex);
84  if (fPlanForward !=NULL)
85  fftw_destroy_plan(fPlanForward);
86  if (fPlanBackward!=NULL)
87  fftw_destroy_plan(fPlanBackward);
88  pthread_mutex_unlock(&fftw_plan_mutex);
89 
90  init();
91 }
MultidimArray< std::complex< double > > fFourier
Definition: xmipp_fftw.h:70
fftw_plan fPlanBackward
Definition: xmipp_fftw.h:76
fftw_plan fPlanForward
Definition: xmipp_fftw.h:73

◆ completeFourierTransform()

template<typename T , typename T1 >
void FourierTransformer::completeFourierTransform ( T &  v,
T1 &  V 
)
inline

Compute the Fourier transform of a MultidimArray, 2D and 3D and returns a complete copy.

Definition at line 315 of file xmipp_fftw.h.

316  {
317  setReal(v);
318  Transform(FFTW_FORWARD);
320  }
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

◆ destroyThreads()

void FourierTransformer::destroyThreads ( void  )
inline

Destroy Threads. Do not execute any previously created plans after calling this function

Definition at line 150 of file xmipp_fftw.h.

151  {
152  nthreads = 1;
153  if(threadsSetOn)
154  fftw_cleanup_threads();
155 
156  threadsSetOn=false;
157  }

◆ enforceHermitianSymmetry()

void FourierTransformer::enforceHermitianSymmetry ( )

Inforce Hermitian symmetry. If the Fourier transform risks of losing Hermitian symmetry, use this function to renforce it.

Definition at line 335 of file xmipp_fftw.cpp.

336 {
337  int ndim=3;
338  int Zdim=ZSIZE(*fReal);
339  int Ydim=YSIZE(*fReal);
340  if (Zdim==1)
341  {
342  ndim=2;
343  if (Ydim==1)
344  ndim=1;
345  }
346  int yHalf=Ydim/2;
347  if (Ydim%2==0)
348  yHalf--;
349  int zHalf=Zdim/2;
350  if (Zdim%2==0)
351  zHalf--;
352  switch (ndim)
353  {
354  case 2:
355  for (int i=1; i<=yHalf; i++)
356  {
357  int isym=intWRAP(-i,0,Ydim-1);
358  std::complex<double> mean=0.5*(
360  conj(DIRECT_A2D_ELEM(fFourier,isym,0)));
361  DIRECT_A2D_ELEM(fFourier,i,0)=mean;
362  DIRECT_A2D_ELEM(fFourier,isym,0)=conj(mean);
363  }
364  break;
365  case 3:
366  for (int k=0; k<Zdim; k++)
367  {
368  int ksym=intWRAP(-k,0,Zdim-1);
369  for (int i=1; i<=yHalf; i++)
370  {
371  int isym=intWRAP(-i,0,Ydim-1);
372  std::complex<double> mean=0.5*(
374  conj(DIRECT_A3D_ELEM(fFourier,ksym,isym,0)));
375  DIRECT_A3D_ELEM(fFourier,k,i,0)=mean;
376  DIRECT_A3D_ELEM(fFourier,ksym,isym,0)=conj(mean);
377  }
378  }
379  for (int k=1; k<=zHalf; k++)
380  {
381  int ksym=intWRAP(-k,0,Zdim-1);
382  std::complex<double> mean=0.5*(
384  conj(DIRECT_A3D_ELEM(fFourier,ksym,0,0)));
385  DIRECT_A3D_ELEM(fFourier,k,0,0)=mean;
386  DIRECT_A3D_ELEM(fFourier,ksym,0,0)=conj(mean);
387  }
388  break;
389  }
390 }
#define YSIZE(v)
alglib::complex conj(const alglib::complex &z)
Definition: ap.cpp:4988
MultidimArray< std::complex< double > > fFourier
Definition: xmipp_fftw.h:70
#define DIRECT_A2D_ELEM(v, i, j)
#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
#define ZSIZE(v)
#define DIRECT_A3D_ELEM(v, k, i, j)
#define intWRAP(x, x0, xF)
Definition: xmipp_macros.h:272

◆ FourierTransform() [1/2]

template<typename T , typename T1 >
void FourierTransformer::FourierTransform ( T &  v,
T1 &  V,
bool  getCopy = true 
)
inline

Compute the Fourier transform of a MultidimArray, 2D and 3D. If getCopy is false, an alias to the transformed data is returned. This is a faster option since a copy of all the data is avoided, but you need to be careful that an inverse Fourier transform may change the data.

Definition at line 166 of file xmipp_fftw.h.

167  {
168  setReal(v);
169  Transform(FFTW_FORWARD);
170  if (getCopy)
171  getFourierCopy(V);
172  else
173  getFourierAlias(V);
174  }
void setReal(MultidimArray< double > &img)
Definition: xmipp_fftw.cpp:129
void Transform(int sign)
Definition: xmipp_fftw.cpp:256
void getFourierAlias(T &V)
Definition: xmipp_fftw.h:207
void getFourierCopy(T &V)
Definition: xmipp_fftw.h:223

◆ FourierTransform() [2/2]

void FourierTransformer::FourierTransform ( )

Compute the Fourier transform. The data is taken from the matrix with which the object was created.

Definition at line 324 of file xmipp_fftw.cpp.

325 {
326  Transform(FFTW_FORWARD);
327 }
void Transform(int sign)
Definition: xmipp_fftw.cpp:256

◆ getCompleteFourier()

template<typename T >
void FourierTransformer::getCompleteFourier ( T &  V)
inline

Return a complete Fourier transform (two halves).

Definition at line 234 of file xmipp_fftw.h.

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  }
#define YSIZE(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY2D(m)
MultidimArray< std::complex< double > > fFourier
Definition: xmipp_fftw.h:70
#define DIRECT_A2D_ELEM(v, i, j)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY3D(V)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY1D(v)
#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
#define DIRECT_A1D_ELEM(v, i)
#define XSIZE(v)
#define ZSIZE(v)
#define DIRECT_A3D_ELEM(v, k, i, j)
#define j

◆ getComplex()

const MultidimArray< std::complex< double > > & FourierTransformer::getComplex ( ) const

Definition at line 123 of file xmipp_fftw.cpp.

124 {
125  return (*fComplex);
126 }
MultidimArray< std::complex< double > > * fComplex
Definition: xmipp_fftw.h:67

◆ getFourierAlias()

template<typename T >
void FourierTransformer::getFourierAlias ( T &  V)
inline

Get Fourier coefficients.

Definition at line 207 of file xmipp_fftw.h.

208  {
209  V.alias(fFourier);
210  return;
211  }
MultidimArray< std::complex< double > > fFourier
Definition: xmipp_fftw.h:70

◆ getFourierCopy()

template<typename T >
void FourierTransformer::getFourierCopy ( T &  V)
inline

Get Fourier coefficients.

Definition at line 223 of file xmipp_fftw.h.

224  {
225  V.resizeNoCopy(fFourier);
227  MULTIDIM_SIZE(fFourier)*2*sizeof(double));
228  }
#define MULTIDIM_SIZE(v)
MultidimArray< std::complex< double > > fFourier
Definition: xmipp_fftw.h:70
#define MULTIDIM_ARRAY(v)

◆ getReal()

const MultidimArray< double > & FourierTransformer::getReal ( ) const

Get the Multidimarray that is being used as input.

Definition at line 118 of file xmipp_fftw.cpp.

119 {
120  return (*fReal);
121 }
MultidimArray< double > * fReal
Definition: xmipp_fftw.h:64

◆ init()

void FourierTransformer::init ( void  )

Definition at line 69 of file xmipp_fftw.cpp.

70 {
71  fReal=NULL;
72  fComplex=NULL;
73  fPlanForward = NULL;
74  fPlanBackward = NULL;
75  dataPtr = NULL;
76  complexDataPtr = NULL;
77 }
MultidimArray< std::complex< double > > * fComplex
Definition: xmipp_fftw.h:67
MultidimArray< double > * fReal
Definition: xmipp_fftw.h:64
fftw_plan fPlanBackward
Definition: xmipp_fftw.h:76
fftw_plan fPlanForward
Definition: xmipp_fftw.h:73
std::complex< double > * complexDataPtr
Definition: xmipp_fftw.h:358

◆ inverseFourierTransform() [1/2]

void FourierTransformer::inverseFourierTransform ( )

Compute the inverse Fourier transform. The result is stored in the same real data that was passed for the forward transform. The Fourier coefficients are taken from the internal Fourier coefficients

Definition at line 329 of file xmipp_fftw.cpp.

330 {
331  Transform(FFTW_BACKWARD);
332 }
void Transform(int sign)
Definition: xmipp_fftw.cpp:256

◆ inverseFourierTransform() [2/2]

template<typename T , typename T1 >
void FourierTransformer::inverseFourierTransform ( T &  V,
T1 &  v 
)
inline

Compute the inverse Fourier transform. New data is provided for the Fourier coefficients and the output can be any matrix1D, 2D or 3D. It is important that the output matrix is already resized to the right size before entering in this function.

Definition at line 198 of file xmipp_fftw.h.

199  {
200  setReal(v);
201  setFourier(V);
202  Transform(FFTW_BACKWARD);
203  }
void setReal(MultidimArray< double > &img)
Definition: xmipp_fftw.cpp:129
void Transform(int sign)
Definition: xmipp_fftw.cpp:256
void setFourier(const MultidimArray< std::complex< double > > &imgFourier)
Definition: xmipp_fftw.cpp:249

◆ operator=()

FourierTransformer & FourierTransformer::operator= ( const FourierTransformer other)

Assignment operator

Definition at line 65 of file xmipp_fftw.cpp.

66 {
67  REPORT_ERROR(ERR_UNCLASSIFIED,"Fourier transformers should not be copied");
68 }
Just to locate unclassified errors.
Definition: xmipp_error.h:192
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211

◆ recomputePlanR2C()

void FourierTransformer::recomputePlanR2C ( )

Recompute transformation plan. Call this method after setting real/fourier alias and before calling Transform() to correctly update this object.

Definition at line 147 of file xmipp_fftw.cpp.

148 {
149  int ndim=3;
150  if (ZSIZE(*fReal)==1)
151  {
152  ndim=2;
153  if (YSIZE(*fReal)==1)
154  ndim=1;
155  }
156  int N[3];
157  switch (ndim)
158  {
159  case 1:
160  N[0]=XSIZE(*fReal);
161  break;
162  case 2:
163  N[0]=YSIZE(*fReal);
164  N[1]=XSIZE(*fReal);
165  break;
166  case 3:
167  N[0]=ZSIZE(*fReal);
168  N[1]=YSIZE(*fReal);
169  N[2]=XSIZE(*fReal);
170  break;
171  }
172 
173  pthread_mutex_lock(&fftw_plan_mutex);
174  if (fPlanForward!=NULL)
175  fftw_destroy_plan(fPlanForward);
176  fPlanForward=NULL;
177  fPlanForward = fftw_plan_dft_r2c(ndim, N, MULTIDIM_ARRAY(*fReal),
178  (fftw_complex*) MULTIDIM_ARRAY(fFourier), FFTW_ESTIMATE);
179  if (fPlanBackward!=NULL)
180  fftw_destroy_plan(fPlanBackward);
181  fPlanBackward=NULL;
182  fPlanBackward = fftw_plan_dft_c2r(ndim, N,
183  (fftw_complex*) MULTIDIM_ARRAY(fFourier), MULTIDIM_ARRAY(*fReal),
184  FFTW_ESTIMATE);
185  if (fPlanForward == NULL || fPlanBackward == NULL)
186  REPORT_ERROR(ERR_PLANS_NOCREATE, "FFTW plans cannot be created");
188  planCreated = true;
189  pthread_mutex_unlock(&fftw_plan_mutex);
190 }
#define YSIZE(v)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
bool planCreated
Definition: xmipp_fftw.cpp:34
MultidimArray< std::complex< double > > fFourier
Definition: xmipp_fftw.h:70
#define MULTIDIM_ARRAY(v)
MultidimArray< double > * fReal
Definition: xmipp_fftw.h:64
fftw_plan fPlanBackward
Definition: xmipp_fftw.h:76
#define XSIZE(v)
#define ZSIZE(v)
fftw_plan fPlanForward
Definition: xmipp_fftw.h:73
FFT Plan cannot be created.
Definition: xmipp_error.h:184

◆ setFourier()

void FourierTransformer::setFourier ( const MultidimArray< std::complex< double > > &  imgFourier)

Set a Multidimarray for the Fourier transform. The values of the input array are copied in the internal array. It is assumed that the container for the real image as well as the one for the Fourier array are already resized. No plan is updated.

Definition at line 249 of file xmipp_fftw.cpp.

250 {
251  memcpy(MULTIDIM_ARRAY(fFourier),MULTIDIM_ARRAY(inputFourier),
252  MULTIDIM_SIZE(inputFourier)*2*sizeof(double));
253 }
#define MULTIDIM_SIZE(v)
MultidimArray< std::complex< double > > fFourier
Definition: xmipp_fftw.h:70
#define MULTIDIM_ARRAY(v)

◆ setFourierAlias()

template<typename T >
void FourierTransformer::setFourierAlias ( T &  V)
inline

Use input as a reference to Fourier data.

Definition at line 215 of file xmipp_fftw.h.

216  {
217  fFourier.alias(V);
218  return;
219  }
MultidimArray< std::complex< double > > fFourier
Definition: xmipp_fftw.h:70
void alias(const MultidimArray< T > &m)

◆ setFromCompleteFourier()

template<typename T >
void FourierTransformer::setFromCompleteFourier ( T &  V)
inline

Set one half of the FT in fFourier from the input complete Fourier transform (two halves). The fReal and fFourier already should have the right sizes

Definition at line 326 of file xmipp_fftw.h.

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:
340  break;
341  case 2:
344  break;
345  case 3:
348  break;
349  }
350  }
#define YSIZE(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY2D(m)
MultidimArray< std::complex< double > > fFourier
Definition: xmipp_fftw.h:70
#define DIRECT_A2D_ELEM(v, i, j)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY3D(V)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY1D(v)
#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
#define DIRECT_A1D_ELEM(v, i)
#define ZSIZE(v)
#define DIRECT_A3D_ELEM(v, k, i, j)
#define j

◆ setNormalizationSign()

void FourierTransformer::setNormalizationSign ( int  _normSign)
inline

Definition at line 416 of file xmipp_fftw.h.

417  {
418  normSign = _normSign;
419  }

◆ setReal() [1/2]

void FourierTransformer::setReal ( MultidimArray< double > &  img)

Set a Multidimarray for input. The data of img will be the one of fReal. In forward transforms it is not modified, but in backward transforms, the result will be stored in img. This means that the size of img cannot change between calls.

Definition at line 129 of file xmipp_fftw.cpp.

130 {
131  bool updatePlan=false;
132  if (fReal==NULL)
133  updatePlan=true;
134  else if (dataPtr!=MULTIDIM_ARRAY(input))
135  updatePlan=true;
136  else
137  updatePlan=!(fReal->sameShape(input));
138  fFourier.resizeNoCopy(ZSIZE(input),YSIZE(input),XSIZE(input)/2+1);
139  fReal=&input;
140 
141  if (updatePlan)
142  {
144  }
145 }
#define YSIZE(v)
void resizeNoCopy(const MultidimArray< T1 > &v)
MultidimArray< std::complex< double > > fFourier
Definition: xmipp_fftw.h:70
#define MULTIDIM_ARRAY(v)
MultidimArray< double > * fReal
Definition: xmipp_fftw.h:64
bool sameShape(const MultidimArrayBase &op) const
#define XSIZE(v)
#define ZSIZE(v)

◆ setReal() [2/2]

void FourierTransformer::setReal ( MultidimArray< std::complex< double > > &  img)

Set a Multidimarray for input. The data of img will be the one of fComplex. In forward transforms it is not modified, but in backward transforms, the result will be stored in img. This means that the size of img cannot change between calls.

Definition at line 192 of file xmipp_fftw.cpp.

193 {
194  bool recomputePlan=false;
195  if (fComplex==NULL)
196  recomputePlan=true;
197  else if (complexDataPtr!=MULTIDIM_ARRAY(input))
198  recomputePlan=true;
199  else
200  recomputePlan=!(fComplex->sameShape(input));
201  fFourier.resizeNoCopy(input);
202  fComplex=&input;
203 
204  if (recomputePlan)
205  {
206  int ndim=3;
207  if (ZSIZE(input)==1)
208  {
209  ndim=2;
210  if (YSIZE(input)==1)
211  ndim=1;
212  }
213  int *N = new int[ndim];
214  switch (ndim)
215  {
216  case 1:
217  N[0]=XSIZE(input);
218  break;
219  case 2:
220  N[0]=YSIZE(input);
221  N[1]=XSIZE(input);
222  break;
223  case 3:
224  N[0]=ZSIZE(input);
225  N[1]=YSIZE(input);
226  N[2]=XSIZE(input);
227  break;
228  }
229 
230  pthread_mutex_lock(&fftw_plan_mutex);
231  if (fPlanForward!=NULL)
232  fftw_destroy_plan(fPlanForward);
233  fPlanForward=NULL;
234  fPlanForward = fftw_plan_dft(ndim, N, (fftw_complex*) MULTIDIM_ARRAY(*fComplex),
235  (fftw_complex*) MULTIDIM_ARRAY(fFourier), FFTW_FORWARD, FFTW_ESTIMATE);
236  if (fPlanBackward!=NULL)
237  fftw_destroy_plan(fPlanBackward);
238  fPlanBackward=NULL;
239  fPlanBackward = fftw_plan_dft(ndim, N, (fftw_complex*) MULTIDIM_ARRAY(fFourier),
240  (fftw_complex*) MULTIDIM_ARRAY(*fComplex), FFTW_BACKWARD, FFTW_ESTIMATE);
241  if (fPlanForward == NULL || fPlanBackward == NULL)
242  REPORT_ERROR(ERR_PLANS_NOCREATE, "FFTW plans cannot be created");
243  delete [] N;
245  pthread_mutex_unlock(&fftw_plan_mutex);
246  }
247 }
#define YSIZE(v)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
void resizeNoCopy(const MultidimArray< T1 > &v)
MultidimArray< std::complex< double > > fFourier
Definition: xmipp_fftw.h:70
#define MULTIDIM_ARRAY(v)
MultidimArray< std::complex< double > > * fComplex
Definition: xmipp_fftw.h:67
bool sameShape(const MultidimArrayBase &op) const
fftw_plan fPlanBackward
Definition: xmipp_fftw.h:76
#define XSIZE(v)
#define ZSIZE(v)
fftw_plan fPlanForward
Definition: xmipp_fftw.h:73
std::complex< double > * complexDataPtr
Definition: xmipp_fftw.h:358
FFT Plan cannot be created.
Definition: xmipp_error.h:184

◆ setThreadsNumber()

void FourierTransformer::setThreadsNumber ( int  tNumber)
inline

Set Number of threads This function, which should be called once, performs any one-time initialization required to use threads on your system.

The nthreads argument indicates the number of threads you want FFTW to use (or actually, the maximum number). All plans subsequently created with any planner routine will use that many threads. You can call fftw_plan_with_nthreads, create some plans, call fftw_plan_with_nthreads again with a different argument, and create some more plans for a new number of threads. Plans already created before a call to fftw_plan_with_nthreads are unaffected. If you pass an nthreads argument of 1 (the default), threads are disabled for subsequent plans.

Definition at line 119 of file xmipp_fftw.h.

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  }
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
Threads cannot be initiated.
Definition: xmipp_error.h:188

◆ Transform()

void FourierTransformer::Transform ( int  sign)

Computes the transform, specified in Init() function If normalization=true the forward transform is normalized (no normalization is made in the inverse transform) If normalize=false no normalization is performed and therefore the image is scaled by the number of pixels.

Definition at line 256 of file xmipp_fftw.cpp.

257 {
258  if (sign == FFTW_FORWARD)
259  {
260  fftw_execute(fPlanForward);
261 
262  if (sign == normSign)
263  {
264  unsigned long int size=0;
265  if(fReal!=NULL)
266  size = MULTIDIM_SIZE(*fReal);
267  else if (fComplex!= NULL)
268  size = MULTIDIM_SIZE(*fComplex);
269  else
270  REPORT_ERROR(ERR_UNCLASSIFIED,"No complex nor real data defined");
271 
272  double isize=1.0/size;
273  double *ptr=(double*)MULTIDIM_ARRAY(fFourier);
274  size_t nmax=(fFourier.nzyxdim/4)*4;
275  for (size_t n=0; n<nmax; n+=4)
276  {
277  *ptr++ *= isize;
278  *ptr++ *= isize;
279  *ptr++ *= isize;
280  *ptr++ *= isize;
281  *ptr++ *= isize;
282  *ptr++ *= isize;
283  *ptr++ *= isize;
284  *ptr++ *= isize;
285  }
286  for (size_t n=nmax; n<fFourier.nzyxdim; ++n)
287  {
288  *ptr++ *= isize;
289  *ptr++ *= isize;
290  }
291  }
292  }
293  else if (sign == FFTW_BACKWARD)
294  {
295  fftw_execute(fPlanBackward);
296 
297  if (sign == normSign)
298  {
299  unsigned long int size=0;
300  if(fReal!=NULL)
301  {
302  size = MULTIDIM_SIZE(*fReal);
303  double isize=1.0/size;
305  DIRECT_MULTIDIM_ELEM(*fReal,n) *= isize;
306  }
307  else if (fComplex!= NULL)
308  {
309  size = MULTIDIM_SIZE(*fComplex);
310  double isize=1.0/size;
311  double *ptr=(double*)MULTIDIM_ARRAY(*fComplex);
313  {
314  *ptr++ *= isize;
315  *ptr++ *= isize;
316  }
317  }
318  else
319  REPORT_ERROR(ERR_UNCLASSIFIED,"No complex nor real data defined");
320  }
321  }
322 }
Just to locate unclassified errors.
Definition: xmipp_error.h:192
int * nmax
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
double sign
#define MULTIDIM_SIZE(v)
MultidimArray< std::complex< double > > fFourier
Definition: xmipp_fftw.h:70
#define MULTIDIM_ARRAY(v)
MultidimArray< std::complex< double > > * fComplex
Definition: xmipp_fftw.h:67
MultidimArray< double > * fReal
Definition: xmipp_fftw.h:64
fftw_plan fPlanBackward
Definition: xmipp_fftw.h:76
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define DIRECT_MULTIDIM_ELEM(v, n)
fftw_plan fPlanForward
Definition: xmipp_fftw.h:73
int * n

Member Data Documentation

◆ complexDataPtr

std::complex<double>* FourierTransformer::complexDataPtr

Definition at line 358 of file xmipp_fftw.h.

◆ dataPtr

double* FourierTransformer::dataPtr

Definition at line 355 of file xmipp_fftw.h.

◆ fComplex

MultidimArray<std::complex<double> >* FourierTransformer::fComplex

Complex array, in fact a pointer to the user array is stored.

Definition at line 67 of file xmipp_fftw.h.

◆ fFourier

MultidimArray< std::complex<double> > FourierTransformer::fFourier

Fourier array

Definition at line 70 of file xmipp_fftw.h.

◆ fPlanBackward

fftw_plan FourierTransformer::fPlanBackward

Definition at line 76 of file xmipp_fftw.h.

◆ fPlanForward

fftw_plan FourierTransformer::fPlanForward

Definition at line 73 of file xmipp_fftw.h.

◆ fReal

MultidimArray<double>* FourierTransformer::fReal

Real array, in fact a pointer to the user array is stored.

Definition at line 64 of file xmipp_fftw.h.

◆ normSign

int FourierTransformer::normSign

Definition at line 85 of file xmipp_fftw.h.

◆ nthreads

int FourierTransformer::nthreads

Definition at line 79 of file xmipp_fftw.h.

◆ threadsSetOn

bool FourierTransformer::threadsSetOn

Definition at line 82 of file xmipp_fftw.h.


The documentation for this class was generated from the following files: