testStationTriggerAlgorithm.cc
Go to the documentation of this file.
1 
11 #include <tst/Verify.h>
12 #include <utl/AugerUnits.h>
13 #include <utl/TimeDistribution.h>
14 #include <utl/Trace.h>
15 #include <sdet/StationTriggerAlgorithm.h>
16 #include <cppunit/extensions/HelperMacros.h>
17 #include <vector>
18 #include <bitset>
19 
20 using namespace std;
21 using namespace sdet;
22 using namespace utl;
23 using namespace tst;
24 using namespace sevt;
25 
26 #define ASSERT_EQUAL(x, y) CPPUNIT_ASSERT(Verify<Equal>(x, y))
27 
28 
29 ostream&
30 operator<<(ostream& os, const StationTriggerInfo& info)
31 {
32  return
33  os << "("
34  "PLD=" << bitset<16>(info.GetPLDBits()) << ", "
35  "T2Th=" << info.IsT2Threshold() << ", "
36  "start=" << info.GetStart() << ", "
37  "latch=" << info.GetLatch() << ", "
38  "stop=" << info.GetStop() << ", "
39  "length=" << info.GetStop() - info.GetStart()
40  << ')';
41 }
42 
43 
44 class TestStationTriggerAlgorithm : public CppUnit::TestFixture {
45 
46  CPPUNIT_TEST_SUITE(TestStationTriggerAlgorithm);
47  CPPUNIT_TEST(TestOneT1ThresholdOnTimeDistributionI);
48  CPPUNIT_TEST(TestOneT2ThresholdOnTimeDistributionI);
49  CPPUNIT_TEST(TestManyT1ThresholdOnTimeDistributionI);
50  //CPPUNIT_TEST(TestOneTOTOnTimeDistributionI);
51  //CPPUNIT_TEST(TestManyTOTOnTimeDistributionI);
52  //CPPUNIT_TEST(TestT1ThresholdAndTOTOnTimeDistributionI);
53  //CPPUNIT_TEST(TestOneTOTdOnTimeDistributionI);
54  //CPPUNIT_TEST(TestOneTOTdOnTimeDistributionIWithBaseline);
55  //CPPUNIT_TEST(TestT1ThresholdOnTraceDWithBaseline);
56  CPPUNIT_TEST_SUITE_END();
57 
58 private:
59  const double fUBSampling = 25*ns;
60  const double fT1Threshold = 1.7;
61  const double fTOTThreshold = 0.2;
62  const double fTOTdThreshold = 0.2;
63  const double fT2Threshold = 3.4;
64  const double fTOTdDecayInBins = 67 / fUBSampling;
65  const int fLatchBin = 246;
66  const int fTraceLength = 3*1024/4;
67  static bool fgShowLegend;
68 
69 public:
71  {
72  if (!fgShowLegend)
73  return;
74  fgShowLegend = false;
75  cerr <<
76  " +----------------- ePLDRandom" "\n"
77  " |" "\n"
78  " | +------------- ePLDTOTC (MoPS)" "\n"
79  " | |+------------ ePLDTOTB (TOTd)" "\n"
80  " | ||+----------- ePLDTOTA (TOT)" "\n"
81  " | |||+---------- ePLDThreshold" "\n"
82  " | ||||" "\n"
83  " | |||| +------ ePLDLatchRandom" "\n"
84  " | |||| |+----- ePLDLatchTOTC (MoPS)" "\n"
85  " | |||| ||+---- ePLDLatchTOTB (TOTd)" "\n"
86  " | |||| |||+--- ePLDLatchTOTA (TOT)" "\n"
87  " | |||| ||||+-- ePLDLatchThreshold" "\n"
88  " | |||| |||||" "\n"
89  " (PLD=f...ba98...43210," "\n"
90  ;
91  }
92 
93  void setUp() override { }
94 
95  void tearDown() override { }
96 
97  void
99  {
100  const double vem = 60;
101  TimeDistributionI trace1(fUBSampling);
102  TimeDistributionI trace2(fUBSampling);
103  TimeDistributionI trace3(fUBSampling);
104  const int bin = -123;
105  trace1[bin] = trace2[bin] = trace3[bin] = 2*vem;
106 
107  const int start = bin - fLatchBin + 1;
108  vector<StationTriggerInfo> info;
109  info.emplace_back(StationTriggerData::ePLDLatchThreshold, false, start, bin, start + fTraceLength);
110 
111  Check(vem, 0, -1000, 2000, trace1, trace2, trace3, info, "one t1th");
112  }
113 
114  void
116  {
117  const int vem = 60;
118  TimeDistributionI trace1(fUBSampling);
119  TimeDistributionI trace2(fUBSampling);
120  TimeDistributionI trace3(fUBSampling);
121  const int bin = -123;
122  trace1[bin] = trace2[bin] = trace3[bin] = 3.5*vem;
123 
124  const int start = bin - fLatchBin + 1;
125  vector<StationTriggerInfo> info;
126  info.emplace_back(StationTriggerData::ePLDLatchThreshold, true, start, bin, start + fTraceLength);
127 
128  Check(vem, 0, -1000, 2000, trace1, trace2, trace3, info, "one t2th");
129  }
130 
131  void
133  {
134  const int vem = 60;
135  TimeDistributionI trace1(fUBSampling);
136  TimeDistributionI trace2(fUBSampling);
137  TimeDistributionI trace3(fUBSampling);
138 
139  const int bin[] = { -1000+300, 0+300, 1000+300 };
140  constexpr int nBits = Length(bin);
141  for (int i = 0; i < nBits; ++i) {
142  trace1[bin[i]] = trace2[bin[i]] = trace3[bin[i]] = 2*vem;
143  trace1[bin[i]+1] = trace2[bin[i]+1] = trace3[bin[i]+1] = 1*vem;
144  }
145 
146  vector<StationTriggerInfo> info;
147  for (int i = 0; i < nBits; ++i) {
148  const int start = bin[i] - fLatchBin + 1;
149  info.emplace_back(StationTriggerData::ePLDLatchThreshold, false, start, bin[i], start + fTraceLength);
150  }
151 
152  Check(vem, 0, -1000, 2000, trace1, trace2, trace3, info, "many t1th");
153  }
154 
155  void
157  {
158  const int vem = 60;
159  TimeDistributionI trace1(fUBSampling);
160  TimeDistributionI trace2(fUBSampling);
161  TimeDistributionI trace3(fUBSampling);
162 
163  // this should latch into T1 threshold
164  const int thBin = -666;
165  trace1[thBin] = trace2[thBin] = trace3[thBin] = 2*vem;
166 
167  // this should give post-latch TOT
168  const int totBin = thBin + 200;
169  const int nCoinc = 15;
170  const int stride = 5; // increased stride so TOTd does not trigger.
171  for (int i = 0; i < nCoinc; ++i) {
172  const int bin = totBin + stride*i;
173  // only 2-fold is required for TOT
174  switch (abs(i%4)) {
175  case 0: trace1[bin] = trace2[bin] = 0.3*vem; break;
176  case 1: trace1[bin] = trace3[bin] = 0.3*vem; break;
177  case 2: trace2[bin] = trace3[bin] = 0.3*vem; break;
178  case 3: trace1[bin] = trace2[bin] = trace3[bin] = 0.3*vem ; break;
179  }
180  }
181 
182  const int start = thBin - fLatchBin + 1;
183  vector<StationTriggerInfo> info;
184  info.emplace_back(
185  StationTriggerData::ePLDLatchThreshold | StationTriggerData::ePLDTOTA, false,
186  start, thBin, start + fTraceLength
187  );
188 
189  Check(vem, 0, -1000, 2000, trace1, trace2, trace3, info, "one t1th and one tot");
190  }
191 
192  void
194  {
195  const int vem = 60;
196  TimeDistributionI trace1(fUBSampling);
197  TimeDistributionI trace2(fUBSampling);
198  TimeDistributionI trace3(fUBSampling);
199 
200  // this should latch TOT
201  const int totBin = 666;
202  const int nCoinc = 20;
203  const int stride = 5; // increased stride so TOTd does not trigger.
204  for (int i = 0; i < nCoinc; ++i) {
205  const int bin = totBin + stride*i;
206  // only 2-fold is required for TOT
207  switch (abs(i%4)) {
208  case 0: trace1[bin] = trace2[bin] = 0.3*vem; break;
209  case 1: trace1[bin] = trace3[bin] = 0.3*vem; break;
210  case 2: trace2[bin] = trace3[bin] = 0.3*vem; break;
211  case 3: trace1[bin] = trace2[bin] = trace3[bin] = 0.4*vem ; break;
212  }
213  }
214 
215  // trigger should fire on 13th
216  const int latch = totBin + (13-1)*stride;
217  const int start = latch - fLatchBin + 1;
218  vector<StationTriggerInfo> info;
219  info.emplace_back(
220  StationTriggerData::ePLDLatchTOTA | StationTriggerData::ePLDTOTA, false,
221  start, latch, start + fTraceLength
222  );
223 
224  Check(vem, 0, -1000, 2000, trace1, trace2, trace3, info, "one tot");
225  }
226 
227  void
229  {
230  const int vem = 60;
231  TimeDistributionI trace1(fUBSampling);
232  TimeDistributionI trace2(fUBSampling);
233  TimeDistributionI trace3(fUBSampling);
234 
235  const int first = -1000;
236  const int last = 2000;
237  const int stride = 5; // increased stride so TOTd does not trigger.
238  // this should latch TOT
239  for (int i = first; i < last; i += stride) {
240  // only 2-fold is required for TOT
241  switch (abs(i % 4)) {
242  case 0: trace1[i] = trace2[i] = 0.3*vem; break;
243  case 1: trace1[i] = trace3[i] = 0.3*vem; break;
244  case 2: trace2[i] = trace3[i] = 0.3*vem; break;
245  case 3: trace1[i] = trace2[i] = trace3[i] = 0.4*vem ; break;
246  }
247  }
248 
249  const int length = last - first;
250  const int traceLength = fTraceLength - (fLatchBin-1);
251  const int nT1 = length/traceLength + bool((length % traceLength)/(12*3 + 1));
252 
253  vector<StationTriggerInfo> info;
254  for (int i = 0; i < nT1; ++i) {
255  const int latch = first + traceLength*i + (13-1)*stride;
256  const int start = latch - fLatchBin + 1;
257  info.emplace_back(
258  StationTriggerData::ePLDLatchTOTA | StationTriggerData::ePLDTOTA, false,
259  start, latch, start + fTraceLength
260  );
261  }
262 
263  Check(vem, 0, first, last, trace1, trace2, trace3, info, "many tot");
264  }
265 
266  void
268  {
269  const int vem = 60;
270  TimeDistributionI trace1(fUBSampling);
271  TimeDistributionI trace2(fUBSampling);
272  TimeDistributionI trace3(fUBSampling);
273 
274  // this should latch TOTd
275  const int totBin = 666;
276  const int nCoinc = 20;
277  const int stride = 2;
278  for (int i = 0; i < nCoinc; ++i) {
279  const int bin = totBin + stride*i;
280  switch (abs(i%7)) {
281  case 0: trace1[bin] = 0.22*vem; break;
282  case 1: trace2[bin] = 0.22*vem; break;
283  case 2: trace3[bin] = 0.22*vem; break;
284  case 3: trace1[bin] = trace2[bin] = 0.22*vem; break;
285  case 4: trace1[bin] = trace3[bin] = 0.22*vem; break;
286  case 5: trace2[bin] = trace3[bin] = 0.22*vem; break;
287  case 6: trace1[bin] = trace2[bin] = trace3[bin] = 0.25*vem ; break;
288  }
289  }
290 
291  // trigger should fire on 18th if multiplicity is 2
292  const int latch = totBin + (18-1)*stride;
293  // trigger should fire on 19th if multiplicity is 3
294  // const int latch = totBin + (19 - 1)*stride;
295  const int start = latch - fLatchBin + 1;
296  vector<StationTriggerInfo> info;
297  info.emplace_back(
298  StationTriggerData::ePLDLatchTOTB | StationTriggerData::ePLDTOTB, false,
299  start, latch, start + fTraceLength
300  );
301  Check(vem, 0, -1000, 2000, trace1, trace2, trace3, info, "two totd");
302 
303  // convolve with exponential response
304  double previous_1 = 0;
305  double previous_2 = 0;
306  double previous_3 = 0;
307  const double rate = exp(-1/fTOTdDecayInBins);
308  for (int bin = totBin; bin < totBin + nCoinc*stride + 10; ++bin) {
309  trace1[bin] += previous_1 * rate;
310  trace2[bin] += previous_2 * rate;
311  trace3[bin] += previous_3 * rate;
312  previous_1 = trace1[bin];
313  previous_2 = trace2[bin];
314  previous_3 = trace3[bin];
315  }
316 
317  info.clear();
318  info.emplace_back(
319  StationTriggerData::ePLDLatchTOTB | StationTriggerData::ePLDTOTB | StationTriggerData::ePLDTOTA, false,
320  start, latch, start + fTraceLength
321  );
322  Check(vem, 0, -1000, 2000, trace1, trace2, trace3, info, "???");
323  }
324 
325  void
327  {
328  const int vem = 60;
329  TimeDistributionI trace1(fUBSampling);
330  TimeDistributionI trace2(fUBSampling);
331  TimeDistributionI trace3(fUBSampling);
332 
333  // this should latch TOTd
334  const int totBin = 666;
335  const int nCoinc = 20;
336  const int stride = 2;
337  for (int i = 0; i < nCoinc; ++i) {
338  const int bin = totBin + stride*i;
339  switch (abs(i%7)) {
340  case 0: trace1[bin] = 0.22*vem; break;
341  case 1: trace2[bin] = 0.22*vem; break;
342  case 2: trace3[bin] = 0.22*vem; break;
343  case 3: trace1[bin] = trace2[bin] = 0.22*vem; break;
344  case 4: trace1[bin] = trace3[bin] = 0.22*vem; break;
345  case 5: trace2[bin] = trace3[bin] = 0.22*vem; break;
346  case 6: trace1[bin] = trace2[bin] = trace3[bin] = 0.25*vem ; break;
347  }
348  }
349 
350  // convolve with exponential response
351  double previous_1 = 0;
352  double previous_2 = 0;
353  double previous_3 = 0;
354  const double rate = exp(-1/fTOTdDecayInBins);
355  for (int bin = totBin; bin < totBin + nCoinc*stride + 10; ++bin) {
356  trace1[bin] += previous_1 * rate;
357  trace2[bin] += previous_2 * rate;
358  trace3[bin] += previous_3 * rate;
359  previous_1 = trace1[bin];
360  previous_2 = trace2[bin];
361  previous_3 = trace3[bin];
362  }
363 
364  // add baseline
365  const double baseline = 50;
366  for (int bin = -1000; bin <= 2000; ++bin) {
367  trace1[bin] += baseline;
368  trace2[bin] += baseline;
369  trace3[bin] += baseline;
370  }
371 
372  // trigger should fire on 18th if multiplicity is 2
373  const int latch = totBin + (18-1)*stride;
374  // trigger should fire on 19th if multiplicity is 3
375  // const int latch = totBin + (19 - 1)*stride;
376  const int start = latch - fLatchBin + 1;
377 
378  vector<StationTriggerInfo> info;
379  info.emplace_back(
380  StationTriggerData::ePLDLatchTOTB | StationTriggerData::ePLDTOTB | StationTriggerData::ePLDTOTA, false,
381  start, latch, start + fTraceLength
382  );
383  Check(vem, baseline, -1000, 2000, trace1, trace2, trace3, info, "one tot (with nonzero baseline)");
384  }
385 
386  /*void
387  TestT1ThresholdOnTraceDWithBaseline()
388  {
389  const double vem = 1;
390  TraceD trace1(fTraceLength, fUBSampling);
391  TraceD trace2(fTraceLength, fUBSampling);
392  TraceD trace3(fTraceLength, fUBSampling);
393  const int bin = fLatchBin - 1;
394  trace1[bin] = trace2[bin] = trace3[bin] = 2*vem;
395 
396  const int start = 0;
397  vector<StationTriggerInfo> info;
398  info.emplace_back(
399  StationTriggerData::ePLDLatchThreshold, false,
400  start, bin, start + fTraceLength
401  );
402 
403  // should produce one T1 threshold
404  Check(vem, 0.1*vem, 0, fTraceLength, trace1, trace2, trace3, info);
405 
406  info.clear();
407 
408  // baseline is too high: no signal
409  Check(vem, 1*vem, 0, fTraceLength, trace1, trace2, trace3, info, "t1th (on trace)");
410  }*/
411 
412 private:
413  template<class Trace>
414  void
415  Check(const double vem, const double baseline,
416  const int first, const int last,
417  const Trace& t1, const Trace& t2, const Trace& t3,
418  const vector<StationTriggerInfo>& shouldGet,
419  const string& comment = "")
420  const
421  {
422  if (!comment.empty())
423  cerr << comment << '\n';
424 
425  using namespace sdet::Trigger;
426 
427  ThresholdUp t1th(int(round(baseline + fT1Threshold*vem)), 3, 3); // multiplicity, n
428  ThresholdUp t2th(int(round(baseline + fT2Threshold*vem)), 3, 3); // multiplicity, n
429  TimeOverThreshold tot(int(round(baseline + fTOTThreshold*vem)), 12, 120, 2, 3); // occupancy, window, multiplicity, n
430  DecayingIntegral integ(122, 0.5, 75., baseline, 3./4, 1./64, 3); // window, delay, decay, n
431  TimeOverThresholdDeconvolved totd(int(round(baseline + fTOTdThreshold*vem)), 45, 54,
432  10, 120, 2, 3); // minCount, window, minIntegral, multiplicity, n
433  MultiplicityOfPositiveSteps mops(4, 121, 3, 31, 3, // occupancy, window, minUp, maxUp, vetoOffset
434  2, 3); // minIntegral, multiplicity, n
435 
436  StationTriggerAlgorithm sTrig(t1th, t2th, tot, integ, totd, mops, fLatchBin, fTraceLength);
437 
438  const vector<const Trace*> traces = { &t1, &t2, &t3 };
439  const vector<StationTriggerInfo> infos = sTrig.Run(first, last, traces);
440  Match(infos, shouldGet);
441  const auto stot = SimpleToT(fTOTThreshold*vem, baseline, 12, 120, 2, first, last, traces);
442  cerr << " SimpleToT " << stot.first << ' ' << stot.second << "\n\n";
443  }
444 
445  static
446  void
447  Match(const vector<StationTriggerInfo>& infos1, const vector<StationTriggerInfo>& infos2)
448  {
449  if (infos1.size() != infos2.size()) {
450  cerr << '\n';
451  for (unsigned int i = 0; i < infos1.size(); ++i)
452  cerr << "trigger info " << i << ": " << infos1[i] << '\n';
453  }
454  ASSERT_EQUAL(infos1.size(), infos2.size());
455  for (unsigned int i = 0; i < infos1.size(); ++i) {
456  const StationTriggerInfo& info1 = infos1[i];
457  const StationTriggerInfo& info2 = infos2[i];
458  cerr << "match " << i+1 << '/' << infos1.size() << ":\n " << info1 << " =?=\n " << info2;
459  ASSERT_EQUAL(info1.GetPLDBits(), info2.GetPLDBits());
460  ASSERT_EQUAL(info1.IsT1(), info2.IsT1());
461  ASSERT_EQUAL(info1.IsT1Threshold(), info2.IsT1Threshold());
462  ASSERT_EQUAL(info1.IsTimeOverThreshold(), info2.IsTimeOverThreshold());
463  ASSERT_EQUAL(info1.IsT2(), info2.IsT2());
464  ASSERT_EQUAL(info1.IsT2Threshold(), info2.IsT2Threshold());
465  ASSERT_EQUAL(info1.GetTrigger(), info2.GetTrigger());
466  ASSERT_EQUAL(info1.GetStart(), info2.GetStart());
467  ASSERT_EQUAL(info1.GetLatch(), info2.GetLatch());
468  ASSERT_EQUAL(info1.GetStop(), info2.GetStop());
469  cerr << " OK\n";
470  }
471  }
472 
473  template<class Trace>
474  static
475  pair<bool, int>
476  SimpleToT(const double totTh, const double baseline,
477  const int occupancy, const int window, const int multiplicity,
478  const int first, const int last,
479  const vector<const Trace*>& traces)
480  {
481  const int maxi = max(last - window, first);
482  for (int i = first; i <= maxi; ++i) {
483  const int maxj = min(i + window, last);
484  int trig = 0;
485  for (int j = i; j <= maxj; ++j) {
486  int m = 0;
487  for (const auto t : traces) {
488  const double s = (*t)[j] - baseline;
489  if (s >= totTh)
490  ++m;
491  }
492  if (m >= multiplicity) {
493  ++trig;
494  if (trig > occupancy)
495  return make_pair(true, j);
496  }
497  }
498  }
499  return make_pair(false, 0);
500  }
501 
502 };
503 
505 
506 
Histogram class for time distributions with suppressed empty bins.
void Check(const double vem, const double baseline, const int first, const int last, const Trace &t1, const Trace &t2, const Trace &t3, const vector< StationTriggerInfo > &shouldGet, const string &comment="") const
static pair< bool, int > SimpleToT(const double totTh, const double baseline, const int occupancy, const int window, const int multiplicity, const int first, const int last, const vector< const Trace * > &traces)
CPPUNIT_TEST_SUITE_REGISTRATION(testAiresShowerFile)
int GetStart() const
First bin of trace.
#define max(a, b)
ostream & operator<<(ostream &os, const Separator< T > &s)
Definition: Util.h:55
constexpr double s
Definition: AugerUnits.h:163
const double ns
double abs(const SVector< n, T > &v)
void Check(const Iterator &i, const Iterator &e, const int id)
a t3: algo, second, usecond and a vector of &lt;t3stat&gt;
Definition: XbT2.h:29
Local station hardware (PLD) and software (T2) trigger algorithm.
int GetStop() const
Last+1 bin of trace.
a second level trigger
Definition: XbT2.h:8
#define ASSERT_EQUAL(x, y)
Template class for a FADC data or calibrated data container. Use the typedefs (TraceD, TraceI, etc.) defined in Trace-fwd.h.
Definition: Trace-fwd.h:19
std::vector< StationTriggerInfo > Run(const int start, const int stop, const std::vector< const Trace< T > * > &traces)
static void Match(const vector< StationTriggerInfo > &infos1, const vector< StationTriggerInfo > &infos2)
constexpr double m
Definition: AugerUnits.h:121

, generated on Tue Sep 26 2023.