Fw2dFFT.cxx
Go to the documentation of this file.
1 // Fw2dFFT.cxx
2 #include "Fw2dFFT.h"
3 #include <iostream>
4 #include <sstream>
5 #include <vector>
6 #include <iomanip>
7 #include "TVirtualFFT.h"
8 #include "TComplex.h"
9 
10 using std::string;
11 using std::cout;
12 using std::cin;
13 using std::endl;
14 using std::vector;
15 using std::setw;
16 using std::fixed;
17 
18 //**********************************************************************
19 // Class methods.
20 //**********************************************************************
21 
23 : m_ndatMax(ndatMax),
24  m_flag(opt==2 ? FFTW_PATIENT : opt==1 ? FFTW_MEASURE : FFTW_ESTIMATE),
25  m_inData(reinterpret_cast<DftFloat*>(fftw_malloc(m_ndatMax*sizeof(DftFloat)))),
26  m_outData(reinterpret_cast<Complex*>(fftw_malloc(m_ndatMax*sizeof(DftFloat)))) { }
27 
28 //**********************************************************************
29 
31  for ( auto& iplan : m_forwardPlans ) fftw_destroy_plan(iplan.second);
32  for ( auto& iplan : m_backwardPlans ) fftw_destroy_plan(iplan.second);
33  fftw_free(m_inData);
34  fftw_free(m_outData);
35 }
36 
37 //**********************************************************************
38 
42  if ( ndatIn > m_ndatMax ) return 1;
43  if ( ndatOut > m_ndatMax ) return 2;
44  if ( ndatIn == 0 ) return 3;
45  return 0;
46 }
47 
48 //**********************************************************************
49 
50 bool Fw2dFFT::haveForwardPlan(const IndexArray& nsams) const {
51  return m_forwardPlans.count(nsams);
52 }
53 
54 //**********************************************************************
55 
56 bool Fw2dFFT::haveBackwardPlan(const IndexArray& nsams) const {
57  return m_backwardPlans.count(nsams);
58 }
59 
60 //**********************************************************************
61 
63  const string myname = "Fw2dFFT::forwardPlan: ";
64  static Plan badplan;
65  if ( checkDataSize(nsams) ) {
66  cout << myname << "Data cannot be accomodated. Maximum data size is " << m_ndatMax << endl;
67  return badplan;
68  }
69  if ( m_forwardPlans.count(nsams) == 0 ) {
70  m_forwardPlans[nsams] = fftw_plan_dft_r2c_2d(nsams[0], nsams[1], m_inData, fftwOutData(), m_flag);
71  }
72  return m_forwardPlans[nsams];
73 }
74 
75 //**********************************************************************
76 
78  const string myname = "Fw2dFFT::backwardPlan: ";
79  static Plan badplan;
80  if ( checkDataSize(nsams) ) {
81  cout << myname << "Data cannot be accomodated. Maximum data size is " << m_ndatMax << endl;
82  return badplan;
83  }
84  if ( m_backwardPlans.count(nsams) == 0 ) {
85  m_backwardPlans[nsams] = fftw_plan_dft_c2r_2d(nsams[0], nsams[1], fftwOutData(), m_inData, m_flag);
86  }
87  return m_backwardPlans[nsams];
88 }
89 
90 //**********************************************************************
91 
92 int Fw2dFFT::
93 fftForward(const Data& dat, DFT& dft, Index logLevel) {
94  const string myname = "Fw2dFFT::fftForward: ";
95  if ( ! dat.isValid() ) return 1;
96  auto nsams = dat.nSamples();
97  dft.reset(nsams);
98  if ( ! dft.isValid() ) return 2;
99  if ( dft.normalization().isPower() ) {
100  cout << myname << "ERROR: Power normalization is not (yet) supported." << endl;
101  return 3;
102  }
103  Index ndatIn = dat.size();
104  Index ndatOut = DFT::dftFloatDataSize(nsams);
105  Plan& plan = forwardPlan(nsams);
106  float fndat = ndatIn;
107  float nfac = dft.normalization().isStandard() ? 1.0 :
108  dft.normalization().isConsistent() ? 1.0/sqrt(fndat) :
109  dft.normalization().isBin() ? 1.0/fndat : 0.0;
110  if ( dat.copyDataOut(m_inData) ) {
111  cout << myname << "ERROR: Copy of input data failed." << endl;
112  return 4;
113  }
114  fftw_execute(plan);
115  dft.reset(nsams);
116  for ( Index idat=0; idat<ndatOut; ++idat ) dft.floatData()[idat] = nfac*floatOutData()[idat];
117  return 0;
118 }
119 
120 //**********************************************************************
121 
122 int Fw2dFFT::
123 fftBackward(const DFT& dft, Data& dat, Index logLevel) {
124  const string myname = "Fw2dFFT::fftBackward: ";
125  if ( ! dft.isValid() ) return 1;
126  auto nsams = dft.nSamples();
127  if ( checkDataSize(nsams) ) {
128  cout << myname << "Sample counts are too large. Maximum data size is " << m_ndatMax << endl;
129  return 2;
130  }
133  if ( dft.normalization().isPower() ) {
134  cout << myname << "ERROR: Power normalization is not (yet) supported." << endl;
135  return 3;
136  }
137  dat.reset(nsams);
138  if ( ! dat.isValid() ) {
139  cout << myname << "ERROR: Unable to initialize output data container." << endl;
140  return 4;
141  }
142  float fndat = ndatIn;
143  float nfac = dft.normalization().isStandard() ? 1.0/fndat :
144  dft.normalization().isConsistent() ? 1.0/sqrt(fndat) :
145  dft.normalization().isBin() ? 1.0 : 0.0;
146  Plan& plan = backwardPlan(nsams);
147  for ( Index idat=0; idat<ndatOut; ++idat ) floatOutData()[idat] = nfac*dft.floatData()[idat];
148  fftw_execute(plan);
149  dat.copyDataIn(m_inData);
150  return 0;
151 }
152 
153 //**********************************************************************
Index checkDataSize(const IndexArray &nsams) const
Definition: Fw2dFFT.cxx:39
int fftForward(const Data &dat, DFT &dft, Index logLevel=0)
Definition: Fw2dFFT.cxx:93
DFT::IndexArray IndexArray
Definition: Fw2dFFT.h:39
Index m_flag
Definition: Fw2dFFT.h:91
std::string string
Definition: nybbler.cc:12
opt
Definition: train.py:196
const IndexArray & nSamples() const
Definition: Real2dData.h:86
struct vector vector
Norm normalization() const override
Plan & backwardPlan(const IndexArray &nsams)
Definition: Fw2dFFT.cxx:77
PlanMap m_forwardPlans
Definition: Fw2dFFT.h:94
FftwComplex * fftwOutData()
Definition: Fw2dFFT.h:83
int fftBackward(const DFT &dft, Data &dat, Index logLevel=0)
Definition: Fw2dFFT.cxx:123
virtual bool isValid() const
Definition: Real2dDftData.h:77
int copyDataOut(T *pdat) const
Definition: Real2dData.h:143
DftFloat * m_inData
Definition: Fw2dFFT.h:92
Index size(Index idim) const
Definition: Real2dData.h:91
Complex * m_outData
Definition: Fw2dFFT.h:93
static Index dataSize(const std::array< Index, N > &nsams)
Definition: Real2dDftData.h:34
void reset(const IndexArray &nsams)
Definition: Real2dData.h:74
void reset(const IndexArray &nsams) override
Plan & forwardPlan(const IndexArray &nsams)
Definition: Fw2dFFT.cxx:62
DFT::Index Index
Definition: Fw2dFFT.h:38
double DftFloat
Definition: Fw2dFFT.h:35
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
bool haveForwardPlan(const IndexArray &nsams) const
Definition: Fw2dFFT.cxx:50
PlanMap m_backwardPlans
Definition: Fw2dFFT.h:95
static Index dftFloatDataSize(const std::array< Index, N > &nsams)
Index m_ndatMax
Definition: Fw2dFFT.h:90
int copyDataIn(const DataVector &data)
Definition: Real2dData.h:121
const IndexArray & nSamples() const override
bool haveBackwardPlan(const IndexArray &nsams) const
Definition: Fw2dFFT.cxx:56
bool isValid() const
Definition: Real2dData.h:102
Fw2dFFT(Index ndatMax, Index opt)
Definition: Fw2dFFT.cxx:22
DFT::Complex Complex
Definition: Fw2dFFT.h:40
QTextStream & endl(QTextStream &s)
fftw_plan Plan
Definition: Fw2dFFT.h:41
DftFloat * floatOutData()
Definition: Fw2dFFT.h:86
~Fw2dFFT()
Definition: Fw2dFFT.cxx:30