test_ExpTailPedRemover.cxx
Go to the documentation of this file.
1 // test_ExpTailPedRemover.cxx
2 //
3 // David Adams
4 // April 2019
5 //
6 // Test ExpTailPedRemover.
7 
8 #include <string>
9 #include <iostream>
10 #include <fstream>
11 #include <sstream>
12 #include <iomanip>
18 #include "TRandom.h"
19 #include "TH1F.h"
20 #include "TGraphErrors.h"
21 
22 #undef NDEBUG
23 #include <cassert>
24 
25 using std::string;
26 using std::cout;
27 using std::endl;
28 using std::ofstream;
29 using std::istringstream;
30 using std::setw;
32 
33 using Index = unsigned int;
34 using IndexVector = std::vector<Index>;
36 
37 //**********************************************************************
38 
39 namespace {
40 
41 struct SigStats {
42  Index count = 0;
43  float rms = 0.0;
44  Index bgcount = 0;
45  float bgmean = 0.0;
46  float bgrms = 0.0;
47  SigStats(const AdcChannelData& acd, const FloatVector& sigTrue, string lab);
48 };
49 
50 SigStats::SigStats(const AdcChannelData& acd, const FloatVector& sigTrue, string lab) {
51  Index nSig = 0;
52  double sumSig2 = 0.0;
53  Index nNsg = 0;
54  double sumNsg = 0.0;
55  double sumNsg2 = 0.0;
56  Index nsam = acd.samples.size();
57  if ( acd.signal.size() < nsam ) return;
58  for ( Index isam=0; isam<nsam; ++isam ) {
59  if ( acd.signal[isam] ) {
60  ++nSig;
61  double sig = acd.samples[isam] - sigTrue[isam];
62  sumSig2 += sig*sig;
63  } else {
64  ++nNsg;
65  double sig = acd.samples[isam];
66  sumNsg += sig;
67  sumNsg2 += sig*sig;
68  }
69  }
70  count = nSig;
71  rms = sqrt(sumSig2/nSig);
72  bgcount = nNsg;
73  bgmean = sumNsg/nNsg;
74  bgrms = sqrt(sumNsg2/nNsg - bgmean*bgmean);
75 
76  if ( lab.size() ) {
77  cout << lab << " # signal: " << count << endl;
78  cout << lab << " # BG: " << bgcount << endl;
79  cout << lab << " BG mean: " << bgmean << endl;
80  cout << lab << " BG RMS: " << bgrms << endl;
81  cout << lab << " Signal RMS: " << rms << endl;
82  }
83 }
84 
85 void drawResults(const FloatVector sigin, const FloatVector& sigraw, const FloatVector& sigout) {
86  const string myname = "drawResults: ";
87  string line = "-----------------------------";
88  cout << myname << line << endl;
89  Index nsam = 300;
90  cout << myname << "Draw data." << endl;
91  LineColors lc;
92  TH1* phi = new TH1F("hin", "ExpTailPedRemover fit;Tick;signal", nsam, 0, nsam);
93  phi->SetStats(0);
94  phi->SetLineWidth(2);
95  phi->SetLineColor(lc.blue());
96  TGraphErrors *pgr = new TGraphErrors(nsam);
97  pgr->SetMarkerStyle(2);
98  pgr->SetMarkerColor(lc.black());
99  TGraphErrors *pgo = new TGraphErrors(nsam);
100  pgo->SetMarkerStyle(24);
101  pgo->SetMarkerColor(lc.red());
102  for ( Index isam=0; isam<nsam; ++ isam ) {
103  phi->SetBinContent(isam+1, sigin[isam]);
104  pgr->SetPoint(isam, isam, sigraw[isam]);
105  pgo->SetPoint(isam, isam, sigout[isam]);
106  }
107  TPadManipulator man(1000, 500);
108  man.add(phi, "HIST");
109  man.add(pgr, "P");
110  man.add(pgo, "P");
111  string fnam = "test_ExpTailPedRemover.png";
112  man.setRangeY(-40, 240);
113  man.addHorizontalLine(0.0);
114  man.addAxis();
115  man.print(fnam);
116  cout << myname << "Plot saved as " << fnam << endl;
117 }
118 
119 } // end unnamed namespace
120 
121 //**********************************************************************
122 
123 int test_ExpTailPedRemover(bool useExistingFcl, Index flag, float ped, float slope, float noiseSigma, bool setSeed) {
124  const string myname = "test_ExpTailPedRemover: ";
125 #ifdef NDEBUG
126  cout << myname << "NDEBUG must be off." << endl;
127  abort();
128 #endif
129  string line = "-----------------------------";
130 
131  cout << myname << line << endl;
132  string fclfile = "test_ExpTailPedRemover.fcl";
133  float decayTime = 100.0;
134  float tail0 = -15.0;
135  int tick0 = 150;
136  int pedDegree = slope == 0.0 ? 0 : 1;
137  if ( ! useExistingFcl ) {
138  cout << myname << "Creating top-level FCL." << endl;
139  ofstream fout(fclfile.c_str());
140  fout << "tools: {" << endl;
141  fout << " sigfind: {" << endl;
142  fout << " tool_type: AdcThresholdSignalFinder" << endl;
143  fout << " LogLevel: 1" << endl;
144  fout << " Threshold: 10" << endl;
145  fout << " BinsAfter: 10" << endl;
146  fout << " BinsBefore: 5" << endl;
147  fout << " FlagPositive: true" << endl;
148  fout << " FlagNegative: true" << endl;
149  fout << " }" << endl;
150  fout << " mytool: {" << endl;
151  fout << " tool_type: ExpTailPedRemover" << endl;
152  fout << " LogLevel: 3" << endl;
153  fout << " SignalFlag: " << flag << endl;
154  fout << " SignalIterationLimit: 10" << endl;
155  fout << " SignalTool: \"sigfind\"" << endl;
156  fout << " DecayTime: " << decayTime << endl;
157  fout << " MaxTick: 400" << endl;
158  fout << " PedDegree: " << pedDegree << endl;
159  fout << " PedTick0: " << tick0 << endl;
160  fout << " PedFreqs: []" << endl;
161  fout << " NoWarnStatuses: []" << endl;
162  fout << " IncludeChannelRanges: [\"all\"]" << endl;
163  fout << " ExcludeChannelRanges: []" << endl;
164  fout << " }" << endl;
165  fout << "}" << endl;
166  fout.close();
167  } else {
168  cout << myname << "Using existing top-level FCL." << endl;
169  }
170 
171  cout << myname << line << endl;
172  cout << myname << "Fetching tool manager." << endl;
174  assert ( ptm != nullptr );
175  DuneToolManager& tm = *ptm;
176  tm.print();
177  assert( tm.toolNames().size() == 2 );
178 
179  cout << myname << line << endl;
180  cout << myname << "Fetching tool." << endl;
181  auto ptoo = tm.getPrivate<TpcDataTool>("mytool");
182  assert( ptoo != nullptr );
183 
184  cout << myname << "Create signals." << endl;
185  Index nsam = 300;
186  FloatVector pulse = { 0.1, 4.5, 15.2, 66.4, 94.3, 100.0, 96.5, 88.4, 72.6, 58.4,
187  42.3, 35.1, 26.0, 18.6, 12.6, 8.8, 6.9, 4.4, 2.0, 0.3 };
188  Index npul = pulse.size();
189  FloatVector sigs1(nsam, 0.0);
190  AdcFilterVector isSignal(nsam, false);
191  IndexVector peakPoss = {70, 100, 115, 230};
192  FloatVector peakAmps = {0.5, 2.0, 0.7, 1.0};
193  Index npea = peakPoss.size();
194  for ( Index ipea=0; ipea<npea; ++ipea ) {
195  Index iposPeak = peakPoss[ipea];
196  float norm = peakAmps[ipea];
197  for ( Index ipul=0; ipul<npul; ++ipul ) {
198  Index isam = iposPeak + ipul;
199  if ( isam >= nsam ) break;
200  sigs1[isam] += norm*pulse[ipul];
201  isSignal[isam] = true;
202  }
203  }
204  FloatVector sigs0 = sigs1;
205 
206  cout << myname << line << endl;
207  cout << myname << "Add noise to the signal." << endl;
208  if ( setSeed ) gRandom->SetSeed();
209  for ( float& sig : sigs1 ) sig += gRandom->Gaus(0.0, noiseSigma);
210 
211  cout << myname << "Create sample tailer." << endl;
212  SampleTailer sta(decayTime);
213  FloatVector peds;
214  float curv = 0.0;
215  if ( slope == 0.0 ) {
216  sta.setPedestal(ped);
217  } else {
218  peds.resize(nsam);
219  for ( Index isam=0; isam<nsam; ++isam ) {
220  float x = float(isam) - tick0;
221  peds[isam] = ped + slope*x + curv*x*x;
222  }
223  sta.setPedestalVector(&peds);
224  }
225  sta.setTail0(tail0);
226  sta.setUnit("ADC count");
227  cout << myname << " decayTime: " << sta.decayTime() << endl;
228  cout << myname << " beta: " << sta.beta() << endl;
229  cout << myname << " alpha: " << sta.alpha() << endl;
230  cout << myname << " pedestal: " << ped << endl;
231  cout << myname << " slope: " << slope << endl;
232  cout << myname << " curvature: " << curv << endl;
233  cout << myname << " tail0: " << sta.tail0() << endl;
234 
235  cout << myname << line << endl;
236  cout << myname << "Add pedestal and tail to the signal to create data." << endl;
237  assert( sta.setSignal(sigs1) == 0 );
238 
239  cout << myname << line << endl;
240  cout << myname << "Create channel data." << endl;
241  AdcChannelData acd;
242  acd.setEventInfo(123, 456);
243  acd.setChannelInfo(789);
244  acd.pedestal = 1000.0;
245  acd.samples = sta.data();
246  acd.signal = isSignal;
247 
248  cout << myname << line << endl;
249  cout << myname << "Check input noise." << endl;
250  SigStats inStats(acd, sigs0, myname);
251  assert( inStats.count > 0 );
252 
253  cout << myname << line << endl;
254  cout << myname << "Use tool to remove tail from data." << endl;
255  DataMap res = ptoo->update(acd);
256  res.print();
257  assert ( res == 0 );
258 
259  cout << myname << line << endl;
260  cout << myname << "Check output noise." << endl;
261  SigStats ouStats(acd, sigs0, myname);
262  assert( ouStats.count > 0 );
263 
264  drawResults(sigs0, sta.data(), acd.samples);
265 
266  cout << myname << "Done." << endl;
267  return 0;
268 }
269 
270 //**********************************************************************
271 
272 int main(int argc, char* argv[]) {
273  bool useExistingFcl = false;
274  Index flag = 2;
275  float noiseSigma = 2.0;
276  float ped = 5.0;
277  float slope = 0.02;
278  bool setSeed = false;
279  if ( argc > 1 ) {
280  string sarg(argv[1]);
281  if ( sarg == "-h" ) {
282  cout << "Usage: " << argv[0] << " [ARG [SLOPE [OPT [noise [setSeed]]]]]" << endl;
283  cout << " If ARG = true, existing FCL file is used." << endl;
284  cout << " SLOPE [0.02] is the pedestal slope" << endl;
285  cout << " OPT [2] is SignalOption = 0, 1, 2, or 3" << endl;
286  cout << " noise [2.0] is the sigma of the noise added to the data" << endl;
287  cout << " setSeed nonzero means a random random seed for the noise" << endl;
288  return 0;
289  }
290  useExistingFcl = sarg == "true" || sarg == "1";
291  }
292  if ( argc > 2 ) {
293  string sarg(argv[2]);
294  istringstream ssarg(sarg);
295  ssarg >> slope;
296  }
297  if ( argc > 3 ) {
298  string sarg(argv[3]);
299  flag = std::stoi(sarg);
300  }
301  if ( argc > 4 ) {
302  string sarg(argv[4]);
303  istringstream ssarg(sarg);
304  ssarg >> noiseSigma;
305  }
306  if ( argc > 5 ) {
307  string sarg(argv[5]);
308  setSeed = sarg != "0";
309  }
310  return test_ExpTailPedRemover(useExistingFcl, flag, ped, slope, noiseSigma, setSeed);
311 }
312 
313 //**********************************************************************
std::vector< Index > IndexVector
double rms(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:40
static ColorType blue()
Definition: LineColors.h:26
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
static ColorType red()
Definition: LineColors.h:27
int setSignal(const FloatVector &inSignal)
static ColorType black()
Definition: LineColors.h:25
void print() const
unsigned int Index
void print(std::ostream *pout) const
Definition: DataMap.h:245
tm
Definition: demo.py:21
int setPedestal(float val)
int addHorizontalLine(double yoff=0.0, double lenfrac=1.0, int isty=1)
void setChannelInfo(ChannelInfoPtr pchi)
const FloatVector & data() const
Definition: SampleTailer.h:88
float decayTime() const
Definition: SampleTailer.h:83
float beta() const
Definition: SampleTailer.h:84
void setEventInfo(EventInfoPtr pevi)
int addAxis(bool flag=true)
int setTail0(float val)
auto norm(Vector const &v)
Return norm of the specified vector.
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
int setPedestalVector(const FloatVector *pval)
std::unique_ptr< T > getPrivate(std::string name)
int main(int argc, char *argv[])
AdcSignal pedestal
AdcFilterVector signal
std::vector< bool > AdcFilterVector
Definition: AdcTypes.h:27
int test_ExpTailPedRemover(bool useExistingFcl, Index flag, float ped, float slope, float noiseSigma, bool setSeed)
void line(double t, double *p, double &x, double &y, double &z)
std::vector< AdcSignal > AdcSignalVector
Definition: AdcTypes.h:22
list x
Definition: train.py:276
float alpha() const
Definition: SampleTailer.h:85
Dft::FloatVector FloatVector
int setRangeY(double y1, double y2)
float tail0() const
Definition: SampleTailer.h:87
int print(std::string fname, std::string spat="{,}")
static DuneToolManager * instance(std::string fclname="", int dbg=1)
AdcSignalVector samples
QTextStream & endl(QTextStream &s)
int setUnit(Name val)
Definition: SampleTailer.h:68