test_AdcChannelFFT.cxx
Go to the documentation of this file.
1 // test_AdcChannelFFT.cxx
2 //
3 // David Adams
4 // April 2017
5 //
6 // Test AdcChannelFFT.
7 
8 #include <string>
9 #include <iostream>
10 #include <fstream>
11 #include <sstream>
12 #include <vector>
13 #include <iomanip>
16 #include <TRandom.h>
17 
18 #undef NDEBUG
19 #include <cassert>
20 
21 using std::string;
22 using std::cout;
23 using std::endl;
24 using std::ostringstream;
25 using std::ofstream;
27 using std::vector;
28 using std::setw;
29 using std::fixed;
30 
31 using Index = unsigned int;
32 
33 //**********************************************************************
34 
35 int test_AdcChannelFFT(bool useExistingFcl, Index len) {
36  const string myname = "test_AdcChannelFFT: ";
37 #ifdef NDEBUG
38  cout << myname << "NDEBUG must be off." << endl;
39  abort();
40 #endif
41  string line = "-----------------------------";
42 
43  cout << myname << line << endl;
44  string fclfile = "test_AdcChannelFFT.fcl";
45  if ( ! useExistingFcl ) {
46  cout << myname << "Creating top-level FCL." << endl;
47  ofstream fout(fclfile.c_str());
48  fout << "tools: {" << endl;
49  fout << " mytool: {" << endl;
50  fout << " tool_type: AdcChannelFFT" << endl;
51  fout << " LogLevel: 2" << endl;
52  fout << " FirstTick: 0" << endl;
53  fout << " NTick: 0" << endl;
54  fout << " NormOpt: 1" << endl;
55  fout << " Action: 3" << endl;
56  fout << " ReturnOpt: 13" << endl;
57  fout << " DataView: \"\"" << endl;
58  fout << " }" << endl;
59  fout << " mytoolinv: {" << endl;
60  fout << " tool_type: AdcChannelFFT" << endl;
61  fout << " LogLevel: 3" << endl;
62  fout << " FirstTick: 0" << endl;
63  fout << " NTick: 0" << endl;
64  fout << " NormOpt: 1" << endl;
65  fout << " Action: 13" << endl;
66  fout << " ReturnOpt: 13" << endl;
67  fout << " DataView: \"\"" << endl;
68  fout << " }" << endl;
69  fout << "}" << endl;
70  fout.close();
71  } else {
72  cout << myname << "Using existing top-level FCL." << endl;
73  }
74 
75  cout << myname << line << endl;
76  cout << myname << "Fetching tool manager." << endl;
78  assert ( ptm != nullptr );
79  DuneToolManager& tm = *ptm;
80  tm.print();
81  assert( tm.toolNames().size() == 2 );
82 
83  cout << myname << line << endl;
84  cout << myname << "Fetching tool." << endl;
85  auto pfft = tm.getPrivate<TpcDataTool>("mytool");
86  assert( pfft != nullptr );
87 
88  cout << myname << line << endl;
89  cout << myname << "Create data." << endl;
90  AdcChannelData acd;
91  acd.setChannelInfo(123);
92  vector<float> sams = { 3.0, 6.0, 16.1, 28.6, 30.2, 27.7, 16.3, 9.6, 4.2, -1.0,
93  -2.3, -4.2, -9.2, -18.6, -21.9, -29.0, -24.3, -14.2, -5.0, -3.0};
94  if ( len > 0 ) sams.resize(len, 0.0);
95  Index nsam = sams.size();
96  assert( sams.size() == nsam );
97  cout << myname << "Sample length: " << nsam << endl;
98  float samsum = 0.0;
99  for ( float sam : sams ) samsum += sam;
100  cout << myname << "Sample mean: " << samsum/nsam << endl;
101  acd.samples = sams;
102  Index nmag = (nsam+2)/2;
103  Index npha = (nsam+1)/2;
104  cout << myname << " # samples: " << nsam << endl;
105  cout << myname << "Expected mag size: " << nmag << endl;
106  cout << myname << "Expected mag size: " << nmag << endl;
107  cout << myname << "Expected pha size: " << npha << endl;
108 
109  cout << myname << line << endl;
110  cout << myname << "Call tool view." << endl;
111  DataMap dm = pfft->view(acd);
112  dm.print();
113  assert( dm == 0 );
114  assert( Index(dm.getInt("fftNTick")) == nsam );
115  assert( Index(dm.getInt("fftTick0")) == 0 );
116  assert( Index(dm.getInt("fftNMag")) == nmag );
117  assert( Index(dm.getInt("fftNPhase")) == npha );
118  assert( dm.haveFloatVector("fftMags") );
119  assert( dm.getFloatVector("fftMags").size() == nmag );
120  assert( dm.haveFloatVector("fftPhases") );
121  assert( dm.getFloatVector("fftPhases").size() == npha );
122  assert( dm.haveFloatVector("fftReals") );
123  assert( dm.getFloatVector("fftReals").size() == nsam );
124  assert( dm.haveFloatVector("fftImags") );
125  assert( dm.getFloatVector("fftImags").size() == nsam );
126 
127  cout << myname << line << endl;
128  cout << myname << "Check power." << endl;
129  float pwr1 = 0.0;
130  for ( float sam : sams ) pwr1 += sam*sam;
131  float pwr2 = 0.0;
132  for ( float mag : dm.getFloatVector("fftMags") ) pwr2 += mag*mag;
133  float pwr3 = 0.0;
134  for ( Index ifrq=0; ifrq<nmag; ++ifrq ) { // We assume power normalization
135  float xre = dm.getFloatVector("fftReals")[ifrq];
136  float xim = dm.getFloatVector("fftImags")[ifrq];
137  pwr3 += xre*xre + xim*xim;
138  }
139  cout << myname << "Tick power: " << pwr1 << endl;
140  cout << myname << "Freq power: " << pwr2 << endl;
141  cout << myname << "Frq2 power: " << pwr3 << endl;
142  assert( fabs(pwr2 - pwr1) < 1.e-5*pwr1 );
143  assert( fabs(pwr3 - pwr1) < 1.e-5*pwr1 );
144 
145  cout << myname << line << endl;
146  cout << myname << "Call tool update." << endl;
147  dm = pfft->update(acd);
148  dm.print();
149  assert( acd.dftmags.size() == nmag );
150  assert( acd.dftphases.size() == npha );
151 
152  cout << myname << line << endl;
153  cout << myname << "Fetching inverse tool." << endl;
154  auto pffi = tm.getPrivate<TpcDataTool>("mytoolinv");
155  assert( pffi != nullptr );
156 
157  cout << myname << line << endl;
158  cout << myname << "Call inverse tool." << endl;
159  acd.samples.clear();
160  assert( acd.samples.size() == 0 );
161  assert( acd.dftmags.size() == nmag );
162  assert( acd.dftphases.size() == npha );
163  dm = pffi->update(acd);
164  dm.print();
165  assert( dm == 0 );
166  assert( acd.samples.size() == nsam );
167  for ( Index isam=0; isam<nsam; ++isam ) {
168  cout << setw(4) << isam << ":" << setw(10) << fixed << acd.samples[isam]
169  << " ?= " << setw(10) << fixed << sams[isam] << endl;
170  assert( fabs(acd.samples[isam] - sams[isam]) < 1.e-4 );
171  }
172 
173  cout << myname << line << endl;
174  cout << myname << "Done." << endl;
175  return 0;
176 }
177 
178 //**********************************************************************
179 
180 int main(int argc, char* argv[]) {
181  bool useExistingFcl = false;
182  Index len = 0;
183  if ( argc > 1 ) {
184  string sarg(argv[1]);
185  if ( sarg == "-h" ) {
186  cout << "Usage: " << argv[0] << " [ARG] [LEN]" << endl;
187  cout << " If ARG = true, existing FCL file is used." << endl;
188  return 0;
189  }
190  useExistingFcl = sarg == "true" || sarg == "1";
191  }
192  if ( argc > 2 ) {
193  string sarg(argv[2]);
194  len = std::stoi(sarg);
195  }
196  return test_AdcChannelFFT(useExistingFcl, len);
197 }
198 
199 //**********************************************************************
const std::vector< std::string > & toolNames() const
std::string string
Definition: nybbler.cc:12
struct vector vector
const FloatVector & getFloatVector(Name name) const
Definition: DataMap.h:221
void print() const
unsigned int Index
void print(std::ostream *pout) const
Definition: DataMap.h:245
tm
Definition: demo.py:21
void setChannelInfo(ChannelInfoPtr pchi)
const double e
int main(int argc, char *argv[])
size_t size
Definition: lodepng.cpp:55
AdcSignalVector dftphases
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
std::unique_ptr< T > getPrivate(std::string name)
unsigned int Index
int getInt(Name name, int def=0) const
Definition: DataMap.h:218
void line(double t, double *p, double &x, double &y, double &z)
bool haveFloatVector(Name name) const
Definition: DataMap.h:210
int test_AdcChannelFFT(bool useExistingFcl, Index len)
static DuneToolManager * instance(std::string fclname="", int dbg=1)
AdcSignalVector samples
AdcSignalVector dftmags
QTextStream & endl(QTextStream &s)