test_Adc2dConvolute.cxx
Go to the documentation of this file.
1 // test_Adc2dConvolute.cxx
2 //
3 // David Adams
4 // April 2019
5 //
6 // Test Adc2dConvolute.
7 
8 #include <string>
9 #include <iostream>
10 #include <fstream>
11 #include <sstream>
12 #include <vector>
13 #include <iomanip>
17 #include <TRandom.h>
18 #include <TH1F.h>
19 #include <TCanvas.h>
20 #include "TLegend.h"
21 
22 #undef NDEBUG
23 #include <cassert>
24 
25 using std::string;
26 using std::cout;
27 using std::endl;
28 using std::ostringstream;
29 using std::istringstream;
30 using std::ofstream;
32 using std::vector;
33 using std::setw;
34 using std::fixed;
35 
36 using Index = unsigned int;
37 using Name = std::string;
38 
39 //**********************************************************************
40 namespace {
41 
42 class Plot {
43 public:
44  TPadManipulator topman;
45  float ymax = 42.0;
46  Plot(Index npad) : topman(400, 800) {
47  topman.split(1, npad);
48  }
49  int addData(const AdcChannelDataMap& data, int col, int lwid, int lsty) {
50  string myname = "Plot::addData: ";
51  Index iman = 0;
52  Name dopt = "HIST";
53  for ( auto& ent : data ) {
54  TPadManipulator* pman = topman.man(iman);
55  if ( pman == nullptr ) {
56  cout << myname << "ERROR: Unable to find subpad " << iman << endl;
57  return 2;
58  }
59  ++iman;
60  Index icha = ent.first;
61  string scha = std::to_string(icha);
62  const AdcSignalVector& sams = ent.second.samples;
63  Index nsam = sams.size();
64  //cout << myname << "Sample count is " << nsam << " for channel " << icha << endl;
65  if ( nsam > 0 ) {
66  Name hnam = "hch" + scha;
67  Name httl = "Channel " + scha + ";Tick;Charge";
68  TH1* ph = new TH1F(hnam.c_str(), httl.c_str(), nsam, 0, nsam);
69  ph->SetStats(0);
70  ph->SetLineWidth(lwid);
71  ph->SetLineStyle(lsty);
72  ph->SetLineColor(col);
73  for ( Index isam=0; isam<nsam; ++isam ) {
74  //cout << myname << "... " << setw(3) << isam << ": " << sams[isam] << endl;
75  ph->Fill(isam+1, sams[isam]);
76  }
77  pman->add(ph, dopt);
78  pman->setGridY();
79  pman->setRangeY(0, ymax);
80  }
81  }
82  //pcan->cd();
83  //ph->Draw(dopt.c_str());
84  return 0;
85  }
86  int print(Name fname) {
87  string myname = "Plot::print: ";
88  topman.draw();
89  //cout << myname << "Printing " << fname << endl;
90  topman.print(fname);
91  return 0;
92  }
93 };
94 
95 bool checkEqual(float x1, float x2) {
96  if ( x1 == x2 ) return true;
97  if ( x1 > 0.0 && x2 > 0.0 ) {
98  return fabs(x1-x2)/x1+x2 < 1.e-6;
99  }
100  return false;
101 }
102 
103 } // end unnamed namepsace
104 //**********************************************************************
105 
106 int test_Adc2dConvolute(bool useExistingFcl) {
107  const string mypre = "test_Adc2dConvolute";
108  const string myname = mypre + ": ";
109 #ifdef NDEBUG
110  cout << myname << "NDEBUG must be off." << endl;
111  abort();
112 #endif
113  string line = "-----------------------------";
114 
115  cout << myname << line << endl;
116  string fclfile = "test_Adc2dConvolute.fcl";
117  // Response has four bins/channels and is defined for central and first neightbor.
118  // The summed response to a unit input bin charge is 1.0 in the central for any bin
119  // and {0.5, 0.25, 0.125, 0.0625} in the neighbor from closest to furthest bin.
120  //
121  if ( ! useExistingFcl ) {
122  cout << myname << "Creating top-level FCL." << endl;
123  ofstream fout(fclfile.c_str());
124  fout << "tools: {" << endl;
125  fout << " mycon: {" << endl;
126  fout << " tool_type: Adc2dConvolute" << endl;
127  fout << " LogLevel: 3" << endl;
128  fout << " ResponseVectors: [" << endl;
129  fout << " [0.2, 0.4, 0.3, 0.1], [0.2, 0.4, 0.3, 0.1]," << endl;
130  fout << " [0.1, 0.2, 0.15, 0.05], [0.05, 0.10, 0.075, 0.025]," << endl;
131  fout << " [0.025, 0.050, 0.0375, 0.0125], [0.0125, 0.025, 0.01875, 0.00625]" << endl;
132  fout << " ]" << endl;
133  fout << " ResponseCenter: 1" << endl;;
134  fout << " BinsPerWire: 4" << endl;;
135  fout << " BinsPerTick: 1" << endl;;
136  fout << " MinChannel: 101" << endl;;
137  fout << " MaxChannel: 104" << endl;;
138  fout << " }" << endl;
139  fout << "}" << endl;
140  fout.close();
141  } else {
142  cout << myname << "Using existing top-level FCL." << endl;
143  }
144 
145  cout << myname << line << endl;
146  cout << myname << "Fetching tool manager." << endl;
148  assert ( ptm != nullptr );
149  DuneToolManager& tm = *ptm;
150  tm.print();
151  assert( tm.toolNames().size() == 1 );
152 
153  cout << myname << line << endl;
154  cout << myname << "Fetching tool." << endl;
155  auto pcondir = tm.getPrivate<TpcDataTool>("mycon");
156  assert( pcondir != nullptr );
157 
158  cout << myname << line << endl;
159  cout << myname << "Create empty input data." << endl;
160  Index nsam = 100;
162  AdcSignalVector empty(nsam, 0.0);
163  for ( Index icha=100; icha<105; ++icha ) {
164  AdcChannelData& acd = data[icha];
165  acd.setEventInfo(123, 456);
166  acd.setChannelInfo(icha);
167  acd.binSamples.resize(4, empty);
168  }
169  std::map<Index,float> expAreas;
170  for ( Index icha=100; icha<106; ++icha ) expAreas[icha] = 0.0;
171 
172  Index nsig = 3;
173  Index isig = 0;
174 
175  if ( isig < nsig ) {
176  cout << myname << "Add signal " << ++isig << endl;
177  data[103].binSamples[3][10] = 100.0;
178  expAreas[102] += 6.25;
179  expAreas[103] += 100.0;
180  expAreas[104] += 50.0;
181  }
182 
183  if ( isig < nsig ) {
184  cout << myname << "Add signal " << ++isig << endl;
185  data[102].binSamples[1][20] = 100.0;
186  expAreas[101] += 25.0;
187  expAreas[102] += 100.0;
188  expAreas[103] += 12.5;
189  }
190 
191  cout << myname << line << endl;
192  cout << myname << "Check signals." << endl;
193  if ( isig < nsig ) {
194  cout << myname << "Add signal " << ++isig << endl;
195  data[101].binSamples[0][30] = 100.0;
196  expAreas[101] += 100.0;
197  expAreas[102] += 6.25;
198  }
199 
200  cout << myname << line << endl;
201  cout << myname << "Check signals." << endl;
202  cout << myname << "Signal count: " << nsig << endl;
203  assert( isig == nsig );
204 
205  cout << myname << line << endl;
206  cout << myname << "Call tool." << endl;
207  DataMap ret = pcondir->updateMap(data);
208  ret.print();
209  assert( ret == 0 );
210  assert( ret.getInt("responseVectorCount") == 6 );
211  assert( ret.getInt("channelMin") == 101 );
212  assert( ret.getInt("channelMax") == 104 );
213 
214  cout << myname << line << endl;
215  cout << myname << "Check areas" << endl;
216  cout << myname << "Chan Nsam Area" << endl;
217  cout << myname << "---- ---- -----------" << endl;
218  for ( const auto& kdat : data ) {
219  Index icha = kdat.first;
220  const AdcSignalVector& sams = kdat.second.samples;
221  //assert( sams.size() == nsam );
222  float area = 0.0;
223  for ( float sam : sams ) area += sam;
224  cout << myname << setw(4) << icha << setw(6) << nsam << setw(13) << area << endl;
225  assert ( checkEqual(area, expAreas[icha]) );
226  }
227 
228  cout << myname << line << endl;
229  string fnam = "convhist.png";
230  cout << myname << "Create plot " << fnam << endl;
231  Plot plt(data.size());
232  plt.addData(data, 1, 2, 1);
233  plt.print(fnam);
234 
235  cout << myname << line << endl;
236  cout << myname << "Done." << endl;
237  return 0;
238 }
239 
240 //**********************************************************************
241 
242 int main(int argc, char* argv[]) {
243  bool useExistingFcl = false;
244  if ( argc > 1 ) {
245  string sarg(argv[1]);
246  if ( sarg == "-h" ) {
247  cout << "Usage: " << argv[0] << " [KEEPFCL [NOISE [SIGMAFIL [NSAM [SETSEED]]]]]" << endl;
248  cout << " KEEPFCL = if 1 (or true), existing FCL file is used [false]" << endl;
249  return 0;
250  }
251  useExistingFcl = sarg == "true" || sarg == "1";
252  }
253  return test_Adc2dConvolute(useExistingFcl);
254 }
255 
256 //**********************************************************************
int setGridY(bool flag=true)
AdcSignalVectorVector binSamples
int add(unsigned int ipad, TObject *pobj, std::string sopt="", bool replace=false)
const std::vector< std::string > & toolNames() const
std::string string
Definition: nybbler.cc:12
struct vector vector
ChannelGroupService::Name Name
int split(Index nx, Index ny)
int main(int argc, char *argv[])
void print() const
int test_Adc2dConvolute(bool useExistingFcl)
unsigned int Index
void print(std::ostream *pout) const
Definition: DataMap.h:245
tm
Definition: demo.py:21
bool checkEqual(string s1, string s2)
void setChannelInfo(ChannelInfoPtr pchi)
void setEventInfo(EventInfoPtr pevi)
TPadManipulator * man(unsigned int ipad=0)
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
std::unique_ptr< T > getPrivate(std::string name)
int getInt(Name name, int def=0) const
Definition: DataMap.h:218
void line(double t, double *p, double &x, double &y, double &z)
std::vector< AdcSignal > AdcSignalVector
Definition: AdcTypes.h:22
std::map< AdcChannel, AdcChannelData > AdcChannelDataMap
int setRangeY(double y1, double y2)
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
int print(std::string fname, std::string spat="{,}")
static DuneToolManager * instance(std::string fclname="", int dbg=1)
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:97
QTextStream & endl(QTextStream &s)