QualityCheck.cxx
Go to the documentation of this file.
1 /*
2  * File: QualityCheck.cxx
3  * Author: mmathis
4  *
5  * Created on June 23, 2010, 12:24 PM
6  */
7 #include <stdio.h>
8 #include <vector>
9 #include "DAQQualityCheck/QualityCheck.h"
10 #include "DAQDataFormats/RawEvent.h"
11 #include "DAQDataFormats/RawDataBlock.h"
12 #include "DAQDataFormats/RawTriggerHeader.h"
13 #include "DAQDataFormats/RawTriggerMask.h"
14 #include <inttypes.h>
15 
16 using namespace daqqc;
17 
18 
19 //Constructors
21  fCheckRun = false;
22  fEventCounter = 0;
23 }
24 
25 
26 //Destructor
28 }
29 
30 
31 #ifndef RAWRUN_IS_NOT_IMPLEMENTED
32 /**
33  * Runs all the desired consistency checks on the RawRun. Returns a single
34  * boolean indicating if all tests were successful, or if there was at least
35  * one problem in at least one of the checks. Individual problems are printed
36  * to the standard output and/or a specified buffer.
37  */
38 bool QualityCheck::checkRun(daqdataformats::RawRun& run) {
39  bool result = true, temp = true;;
40  fRun = run;
41  fCheckRun = true;
42  std::cout << "Running some checks on the run" << std::endl;
43 
44  fPartition = fRun.getPartition();
45  fRunNum = fRun.getRunNumber();
46  fSubrunNum = fRun.getSubrun();
47  fSim = fRun.getTriggerMC();
48  fEventCounter = fRun.getUniversalEventStart();
49 
50  // Check the CRC for the entire run
51  if (fRun.calculateCheckSum(0) != 0) {
52  result = false;
53  std::cout << "QC ERROR: Run CRC checksum is wrong" << std::endl;
54  }
55 
56  temp = checkRunHeaderTail(fRun.getHeader(), fRun.getTail());
57  if (!result && temp)
58  result = false;
59  else
60  result = temp;
61 
62  temp = checkConfigBlock(fRun.getConfigurationBlock());
63  if (!result && temp)
64  result = false;
65  else
66  result = temp;
67 
68  // Run checks on each event
69  for (uint32_t ievt = 0; ievt < fRun.getTotalEvents(); ievt++) {
70  fRun.setFloatingEvent(ievt);
71  daqdataformats::RawEvent* event = fRun.getFloatingEvent();
72 
73  if (ievt == 0) {
74  if (event->getTrigger()->getTriggerTimingMarker()->getTriggerStart_baseClock() != fRun.getHeader()->getRunStartTime()) {
75  result = false;
76  std::cout << "QC ERROR: Run start time not consistent with first event's trigger time" << std::endl;
77  }
78  } // if ievt = 0
79  if (ievt == fRun.getTotalEvents() - 1) {
80  if (event->getTrigger()->getTriggerTimingMarker()->getTriggerStart_baseClock() != fRun.getHeader()->getRunEndTime()) {
81  result = false;
82  std::cout << "QC ERROR: Run end time not consistent with last event's trigger time" << std::endl;
83  }
84  } // if ievt
85 
86  temp = checkEvent(event);
87  if (!result && temp)
88  result = false;
89  else
90  result = temp;
91 
92  fEventCounter++;
93  }
94 
95  return result;
96 } // checkRun
97 #endif
98 
99 /**
100  * Runs all the desired consistency checks on the RawEvent. Returns a single
101  * boolean indicating if all tests were successful, or if there was at least
102  * one problem in at least one of the checks. The return value does not
103  * specify what went wrong, only that something did go wrong. Individual
104  * problems are printed to the standard output and/or a specified buffer.
105  * @param event The event to check
106  */
108  bool result = true, temp = true;
109  fEvent = event;
110 
111  std::cout << "\nChecking the event" << std::endl;
112 
113  // First, do the CRC checksum for the entire event
114  if (fEvent.isCRCCalculationUsed()) {
115  if (fEvent.calculateCheckSum(0) != 0) {
116  result = false;
117  std::cout << "QC ERROR: Event CRC checksum wrong" << std::endl;
118  }
119  }
120 
121  fEventNum = event.getEventNumber();
122  fTrigger = event.getTrigger()->getTriggerHeader()->getTriggerNumber();
123 
124  if (fCheckRun) {
125  if (fEventNum != fEventCounter) {
126  result = false;
127  std::cout << "QC ERROR: Event number did not increment correctly" << std::endl;
128  }
129  } else {
130  fPartition = event.getPartition();
131  fSim = event.getMonteCarloFlag();
132  }
133 
134  temp = checkTriggerBlock(event.getTrigger());
135  if (!result && temp)
136  result = false;
137  else
138  result = temp;
139 
140  temp = checkEventHeaderTail(event.getHeader(), event.getTail());
141  if (!result && temp)
142  result = false;
143  else
144  result = temp;
145 
146  // Loop over the datablocks
147  uint32_t ndata = event.getDataBlockNumber();
148  for (uint32_t idata = 0; idata < ndata; idata++) {
149  event.setFloatingDataBlock(idata);
150  daqdataformats::RawDataBlock* data = event.getFloatingDataBlock();
151 
152  temp = checkDataBlock(data, idata);
153  if (!result && temp)
154  result = false;
155  else
156  result = temp;
157 
158  // Loop over micro-blocks
159  uint16_t nmicrob = data->getNumMicroBlocks();
160  for (uint16_t imicrob = 0; imicrob < nmicrob; imicrob++) {
161  data->setFloatingMicroBlock(imicrob);
162  daqdataformats::RawMicroBlock* microblock = (daqdataformats::RawMicroBlock*)data->getFloatingMicroBlock();
163  daqdataformats::RawMicroBlockHeader* microhead = (daqdataformats::RawMicroBlockHeader*)microblock->getHeader();
164  // Check partition in Microblock header
165  if (microhead->getPartition() != fPartition) {
166  result = false;
167  std::cout << "QC ERROR: Datablock " << idata << ", Microblock " << imicrob << " partition wrong: " << microhead->getPartition() << std::endl;
168  }
169 
170  // There is only 1 micro slice per micro block
171  daqdataformats::RawMicroSlice* micro = microblock->getMicroSlice();
172  temp = checkMicroSlice(micro, idata, imicrob);
173  if (!result && temp)
174  result = false;
175  else
176  result = temp;
177 
178  // Loop over nanoslices in this microslice
179  uint32_t nnano = micro->getNumNanoSlices();
180  for (uint32_t inano = 0; inano < nnano; inano++) {
181  micro->setFloatingNanoSlice(inano);
183  temp = checkNanoSlice(nano);
184  if (!result && temp)
185  result = false;
186  else
187  result = temp;
188 
189  } // loop over nanoslices
190  } // loop over microblocks
191  } // loop over datablocks
192 
193  return result;
194 } // runEventChecks
195 
196 
197 /**
198  * Helper function to run all the desired consistency checks on the
199  * RawEvent. Returns a single
200  * boolean indicating if all tests were successful, or if there was at least
201  * one problem in at least one of the checks.
202  * @param event The event to check
203  */
205  bool result = true, temp = true;
206 
207  std::cout << "Checking the event" << std::endl;
208 
209  // First, do the CRC checksum for the entire event
210  if (event->isCRCCalculationUsed()) {
211  if (event->calculateCheckSum(0) != 0) {
212  result = false;
213  std::cout << "QC ERROR: Event CRC checksum wrong" << std::endl;
214  }
215  }
216 
217  fEventNum = event->getEventNumber();
218  fTrigger = event->getTrigger()->getTriggerHeader()->getTriggerNumber();
219 
220  if (fCheckRun) {
221  if (fEventNum != fEventCounter) {
222  result = false;
223  std::cout << "QC ERROR: Event number did not increment correctly" << std::endl;
224  }
225  } else {
226  fPartition = event->getPartition();
227  fSim = event->getMonteCarloFlag();
228  }
229 
230  temp = checkTriggerBlock(event->getTrigger());
231  if (!result && temp)
232  result = false;
233  else
234  result = temp;
235  temp = checkEventHeaderTail(event->getHeader(), event->getTail());
236  if (!result && temp)
237  result = false;
238  else
239  result = temp;
240 
241  // Loop over the data-blocks
242  uint32_t ndata = event->getDataBlockNumber();
243  for (uint32_t idata = 0; idata < ndata; idata++) {
244  event->setFloatingDataBlock(idata);
245  daqdataformats::RawDataBlock* data = event->getFloatingDataBlock();
246 
247  temp = checkDataBlock(data, idata);
248  if (!result && temp)
249  result = false;
250  else
251  result = temp;
252 
253  // Loop over micro-blocks
254  uint16_t nmicrob = data->getNumMicroBlocks();
255  for (uint16_t imicrob = 0; imicrob < nmicrob; imicrob++) {
256  data->setFloatingMicroBlock(imicrob);
257  daqdataformats::RawMicroBlock* microblock = (daqdataformats::RawMicroBlock*)data->getFloatingMicroBlock();
258  daqdataformats::RawMicroBlockHeader* microhead = (daqdataformats::RawMicroBlockHeader*)microblock->getHeader();
259  // Check partition in Microblock header
260  if (microhead->getPartition() != fPartition) {
261  result = false;
262  std::cout << "QC ERROR: Datablock " << idata << ", Microblock " << imicrob << " partition wrong: " << microhead->getPartition() << std::endl;
263  }
264 
265  // There is only 1 micro slice per micro block
266  daqdataformats::RawMicroSlice* micro = microblock->getMicroSlice();
267  temp = checkMicroSlice(micro, idata, imicrob);
268  if (!result && temp)
269  result = false;
270  else
271  result = temp;
272 
273  // Loop over nanoslices in this microslice
274  uint32_t nnano = micro->getNumNanoSlices();
275  for (uint32_t inano = 0; inano < nnano; inano++) {
276  micro->setFloatingNanoSlice(inano);
278  temp = checkNanoSlice(nano);
279  if (!result && temp)
280  result = false;
281  else
282  result = temp;
283 
284  } // loop over nanoslices
285  } // loop over microblocks
286  } // loop over datablocks
287 
288  return result;
289 } // runEventChecks
290 
291 
292 /**
293  * Helper to check that the run header and tail are consistent
294  * with each other
295  * @param header The run header
296  * @param tail The run tail. Note that it is of type RawRunHeader, as they
297  * have the same structure
298  */
300  bool result = true;
301  std::cout << "Checking the run header and tail" << std::endl;
302 
303  // Check markers in header
304  if (header->getMarkerHi() != 0x41764F4E) {
305  result = false;
306  std::cout << "QC ERROR: Run header high marker NOvA is wrong" << std::endl;
307  }
308  if (header->getMarkerLo() != 0x39323945) {
309  result = false;
310  std::cout << "QC ERROR: Run header low marker E929 is wrong" << std::endl;
311  }
312 
313  // Check markers in tail
314  if (tail->getMarkerHi() != 0x4C494154) {
315  result = false;
316  std::cout << "QC ERROR: Run tail upper high marker TAIL is wrong" << std::endl;
317  }
318  if (tail->getMarkerLo() != 0x4C494154) {
319  result = false;
320  std::cout << "QC ERROR: Run tail upper low marker TAIL is wrong" << std::endl;
321  }
322  if (tail->getReserved1() != 0x39323945) {
323  result = false;
324  std::cout << "QC ERROR: Run tail lower high marker E929 is wrong" << std::endl;
325  }
326  if (tail->getReserved2() != 0x41764F4E) {
327  result = false;
328  std::cout << "QC ERROR: Run tail lower low marker NOvA is wrong" << std::endl;
329  }
330 
331  // Check that various quantities are consistent between header and tail
332  if (header->getRunNumber() != tail->getRunNumber()) {
333  result = false;
334  std::cout << "QC ERROR: Run number not consistent between run header and tail" << std::endl;
335  }
336  if (header->getRunType() != tail->getRunType()) {
337  result = false;
338  std::cout << "QC ERROR: Run type not consistent between run header and tail" << std::endl;
339  }
340  if (header->getSubrun() != tail->getSubrun()) {
341  result = false;
342  std::cout << "QC ERROR: Subrun number not consistent between run header and tail" << std::endl;
343  }
344  if (header->getPartition() != tail->getPartition()) {
345  result = false;
346  std::cout << "QC ERROR: Partition not consistent between run header and tail" << std::endl;
347  }
348  if (header->getRunControlVersion() != tail->getRunControlVersion()) {
349  result = false;
350  std::cout << "QC ERROR: Run control version not consistent between run header and tail" << std::endl;
351  }
352  if (header->getRunControlID() != tail->getRunControlID()) {
353  result = false;
354  std::cout << "QC ERROR: Run control ID not consistent between run header and tail" << std::endl;
355  }
356  if (header->getDataLoggerVersion() != tail->getDataLoggerVersion()) {
357  result = false;
358  std::cout << "QC ERROR: Datalogger version not consistent between run header and tail" << std::endl;
359  }
360  if (header->getDataLoggerID() != tail->getDataLoggerID()) {
361  result = false;
362  std::cout << "QC ERROR: Datalogger ID not consistent between run header and tail" << std::endl;
363  }
364  if (header->getRunStartTime() != tail->getRunStartTime()) {
365  result = false;
366  std::cout << "QC ERROR: Run start time not consistent between run header and tail" << std::endl;
367  }
368  if (header->getRunEndTime() != tail->getRunEndTime()) {
369  result = false;
370  std::cout << "QC ERROR: Run end time not consistent between run header and tail" << std::endl;
371  }
372  if (header->getSubRunStartTime() != tail->getSubRunStartTime()) {
373  result = false;
374  std::cout << "QC ERROR: Subrun start time not consistent between run header and tail" << std::endl;
375  }
376  if (header->getSubRunEndTime() != tail->getSubRunEndTime()) {
377  result = false;
378  std::cout << "QC ERROR: Subrun end time not consistent between run header and tail" << std::endl;
379  }
380  if (header->getUniversalEventStart() != tail->getUniversalEventStart()) {
381  result = false;
382  std::cout << "QC ERROR: Universal event start not consistent between run header and tail" << std::endl;
383  }
384  if (header->getUniversalEventEnd() != tail->getUniversalEventEnd()) {
385  result = false;
386  std::cout << "QC ERROR: Universal event end not consistent between run header and tail" << std::endl;
387  }
388  if (header->getRunSize() != tail->getRunSize()) {
389  result = false;
390  std::cout << "QC ERROR: Run size not consistent between run header and tail" << std::endl;
391  }
392  if (header->getTriggerCtrlID() != tail->getTriggerCtrlID()) {
393  result = false;
394  std::cout << "QC ERROR: Trigger control ID not consistent between run header and tail" << std::endl;
395  }
396  if (header->getTriggerVersion() != tail->getTriggerVersion()) {
397  result = false;
398  std::cout << "QC ERROR: Trigger version not consistent between run header and tail" << std::endl;
399  }
400  if (header->getTriggerMC() != tail->getTriggerMC()) {
401  result = false;
402  std::cout << "QC ERROR: SIM flag not consistent between run header and tail" << std::endl;
403  }
404  if (header->getVTMod() != tail->getVTMod()) {
405  result = false;
406  std::cout << "QC ERROR: VT Mod not consistent between run header and tail" << std::endl;
407  }
408  if (header->getTriggerPrescaleListIDX() != tail->getTriggerPrescaleListIDX()) {
409  result = false;
410  std::cout << "QC ERROR: Trigger prescale list IDX not consistent between run header and tail" << std::endl;
411  }
412  if (header->getTriggerListIDX() != tail->getTriggerListIDX()) {
413  result = false;
414  std::cout << "QC ERROR: Trigger list IDX not consistent between run header and tail" << std::endl;
415  }
416 
417  if ((header->getValidTriggerTypesLow() != tail->getValidTriggerTypesLow()) &&
418  (header->getValidTriggerTypesHigh() != tail->getValidTriggerTypesHigh()) &&
419  (header->getValidTriggerTypesHigh2() != tail->getValidTriggerTypesHigh2())) {
420  result = false;
421  std::cout << "QC ERROR: Valid trigger types not consistent between run header and tail" << std::endl;
422  }
423 
424  // Check that the num events = event end - event start + 1
425  if (header->getUniversalEventEnd() - header->getUniversalEventStart() + 1 != header->getTotalEvents()) {
426  result = false;
427  std::cout << "QC ERROR: Run header number of events not consistent with start and end event numbers" << std::endl;
428  }
429 
430  // Check the CRC checksums in the header and tail
431  if (header->calculateCheckSum(0) != 0) {
432  result = false;
433  std::cout << "QC ERROR: Run header checksum failed" << std::endl;
434  }
435 
436  if (tail->calculateCheckSum(0) != 0) {
437  result = false;
438  std::cout << "QC ERROR: Run tail checksum failed" << std::endl;
439  }
440 
441  // Check to make sure some values are non-zero
442  if (header->getRunControlVersion() == 0) {
443  result = false;
444  std::cout << "QC ERROR: Run header Run control version is zero (0)" << std::endl;
445  }
446  if (header->getRunControlID() == 0) {
447  result = false;
448  std::cout << "QC ERROR: Run header Run control ID is zero (0)" << std::endl;
449  }
450  if (header->getDataLoggerVersion() == 0) {
451  result = false;
452  std::cout << "QC ERROR: Run headerDatalogger version is zero (0)" << std::endl;
453  }
454  if (header->getDataLoggerID() == 0) {
455  result = false;
456  std::cout << "QC ERROR: Run header Datalogger ID is zero (0)" << std::endl;
457  }
458  if (header->getRunSize() == 0) {
459  result = false;
460  std::cout << "QC ERROR: Run header run size is zero (0)" << std::endl;
461  }
462  if (header->getTriggerCtrlID() == 0) {
463  result = false;
464  std::cout << "QC ERROR: Run header trigger control ID is zero (0)" << std::endl;
465  }
466  if (header->getTriggerVersion() == 0) {
467  result = false;
468  std::cout << "QC ERROR: Run header trigger version is zero (0)" << std::endl;
469  }
470  /*if (header->getVTMod() == 0) {
471  result = false;
472  std::cout << "QC ERROR: Run header VT Mod is zero (0)" << std::endl;
473  }*/
474  if (header->getTriggerPrescaleListIDX() == 0) {
475  result = false;
476  std::cout << "QC ERROR: Run header trigger prescale list IDX is zero (0)" << std::endl;
477  }
478  if (header->getTriggerListIDX() == 0) {
479  result = false;
480  std::cout << "QC ERROR: Run header trigger list IDX is zero (0)" << std::endl;
481  }
482 
483  return result;
484 } // checkRunHeaderTail
485 
486 
487 /**
488  * Helper to check that the config block is consistent with the run header
489  * @param config The Configuration Block
490  */
492  bool result = true;
493  std::cout << "Checking the configuration block" << std::endl;
494  //config->print();
495 
496  // First, ckeck the CRC checksum
497  if (config->calculateCheckSum(0) != 0) {
498  result = false;
499  std::cout << "QC ERROR: Config block checksum failed" << std::endl;
500  }
501 
502  // Now check the markers
503  if (config->getMarkerHi1() != 0x464E4F43) {
504  result = false;
505  std::cout << "QC ERROR: Config block first marker CONF is wrong" << std::endl;
506  }
507  if (config->getMarkerHi2() != 0x54525453) {
508  result = false;
509  std::cout << "QC ERROR: Config block second marker STRT is wrong" << std::endl;
510  }
511  if (config->getMarkerLo1() != 0x464E4F43) {
512  result = false;
513  std::cout << "QC ERROR: Config block third marker CONF is wrong" << std::endl;
514  }
515  if (config->getMarkerLo2() != 0x44444E45) {
516  result = false;
517  std::cout << "QC ERROR: Config block fourth marker ENDD is wrong: " << config->getMarkerLo2() << ", " << config->getMarkerLo1() << std::endl;
518  }
519 
520  #ifndef RAWRUN_IS_NOT_IMPLEMENTED
521  // Check run number, type, etc are consistent with run header
522  if (config->getRunType() != fRun.getRunType()) {
523  result = false;
524  std::cout << "QC ERROR: Config block run type is not consistent with run header" << std::endl;
525  }
526 #endif
527  if (config->getRunNumber() != fRunNum) {
528  result = false;
529  std::cout << "QC ERROR: Config block run number is not consistent with run header" << std::endl;
530  }
531  if (config->getSubrun() != fSubrunNum) {
532  result = false;
533  std::cout << "QC ERROR: Config block subrun number is not consistent with run header" << std::endl;
534  }
535  if (config->getPartition() != fPartition) {
536  result = false;
537  std::cout << "QC ERROR: Config block partition number is not consistent with run header" << std::endl;
538  }
539  /* if (config->getConfigIDX() != fRun.getConfigIDX()) {
540  result = false;
541  std::cout << "QC ERROR: Config block Config IDX is not consistent with run header" << std::endl;
542  }
543  */
544  // Check to make sure some values are non-zero
545  if (config->getConfigurationVersion() == 0) {
546  result = false;
547  std::cout << "QC ERROR: Config block header version number is zero (0)" << std::endl;
548  }
549  if (config->getResourceManagerID() == 0) {
550  result = false;
551  std::cout << "QC ERROR: Config block resource manager ID is zero (0)" << std::endl;
552  }
553  if (config->getSystemVersionIDX() == 0) {
554  result = false;
555  std::cout << "QC ERROR: Config block system version IDX is zero (0)" << std::endl;
556  }
557  if (config->getSystemNumber() == 0) {
558  result = false;
559  std::cout << "QC ERROR: Config block number of systems is zero (0)" << std::endl;
560  }
561  /* if (config->getConfigIDX() == 0) {
562  result = false;
563  std::cout << "QC ERROR: Config block config IDX is zero (0)" << std::endl;
564  }*/
565  // Check ID and version numbers of all systems to make sure they are non-zero
566  for (uint32_t i = 1; i < config->getSystemNumber(); i++) {
567  if (config->getSystemID(i) == 0) {
568  result = false;
569  std::cout << "QC ERROR: Config block DAQ system ID " << i << " is zero (0)" << std::endl;
570  }
571  }
572 
573  return result;
574 } // checkConfigBlock
575 
576 
577 /**
578  * Helper to check that the event header and tail are consistent
579  * with each other
580  * @param header The event header
581  * @param tail The event tail
582  */
584  bool result = true;
585 
586  std::cout << "Checking event header/tail:" << std::endl;
587 
588  // Check markers in the header
589  if (header->getMarkerLeft() != 0xE929) {
590  result = false;
591  std::cout << "QC ERROR: Event header 0xE929 left marker wrong" << std::endl;
592  }
593 
594  if (header->getMarkerRight() != 0xE929) {
595  result = false;
596  std::cout << "QC ERROR: Event header 0xE929 right marker wrong" << std::endl;
597  }
598 
599  // Check markers in the tail
600  if (tail->getMarker() != 0xEEEE) {
601  result = false;
602  std::cout << "QC ERROR: Event tail 0xEEEE marker wrong" << std::endl;
603  }
604 
605  if (tail->getMarkerLeft() != 0x929E) {
606  result = false;
607  std::cout << "QC ERROR: Event tail 0x929E left marker wrong" << std::endl;
608  }
609 
610  if (tail->getMarkerRight() != 0x929E) {
611  result = false;
612  std::cout << "QC ERROR: Event tail 0x929E right marker wrong" << std::endl;
613  }
614 
615  // Check version number is non-zero in header
616  if (header->getVersion() == 0) {
617  result = false;
618  std::cout << "QC ERROR: Event header version number is zero (0)" << std::endl;
619  }
620 
621 
622  // If part of a run, check some values are consistent with run, or check
623  // that they're non-zero
624  if (fCheckRun) {
625 #ifndef RAWRUN_IS_NOT_IMPLEMENTED
626  if (header->getDataLoggerID() != fRun.getDataLoggerID()) {
627  result = false;
628  std::cout << "QC ERROR: Event header datalogger ID is not consistent with run header" << std::endl;
629  }
630  if (header->getRunType() != fRun.getRunType()) {
631  result = false;
632  std::cout << "QC ERROR: Event header run type is not consistent with run header" << std::endl;
633  }
634  if (header->getConfigIDX() != fRun.getConfigIDX()) {
635  result = false;
636  std::cout << "QC ERROR: Event header ConfigIDX is not consistent with run header" << std::endl;
637  }
638 #endif
639  if (header->getRunNumber() != fRunNum) {
640  result = false;
641  std::cout << "QC ERROR: Event header run number is not consistent with run header" << std::endl;
642  }
643  if (header->getSubrun() != fSubrunNum) {
644  result = false;
645  std::cout << "QC ERROR: Event header subrun number is not consistent with run header" << std::endl;
646  }
647 
648  } else { // check that some values are non-zero
649  if (header->getDataLoggerID() == 0) {
650  result = false;
651  std::cout << "QC ERROR: Event header datalogger ID is zero (0)" << std::endl;
652  }
653  if (header->getConfigIDX() == 0) {
654  result = false;
655  std::cout << "QC ERROR: Event header ConfigIDX is zero (0)" << std::endl;
656  }
657  } // if fCheckRun
658 
659  // Check event number and event size consistent
660  uint64_t tailEventNum;
661  uint32_t low, high;
662 
663  low = tail->getEventNumberLo();
664  high = tail->getEventNumberHi();
665 
666  tailEventNum = (uint64_t)high << 32 | low;
667 
668  if (tailEventNum != header->getEventNumber()) {
669  result = false;
670  std::cout << "QC ERROR: Event tail event number wrong: " << tailEventNum << std::endl;
671  }
672 
673  if (tail->getEventSize() != header->getEventSize()) {
674  result = false;
675  std::cout << "QC ERROR: Event tail event size wrong:" << tail->getEventSize() << std::endl;
676  }
677 
678  return result;
679 } // checkEventHeaderTail
680 
681 
682 /**
683  * Helper to perform checks on the Trigger block
684  * @param trigger The trigger block to check
685  */
687  bool result = true;
688  std::cout << "Check trigger" << std::endl;
689 
690  // Check marker in header
691  if (trigger->getTriggerHeader()->getDelimiter() != 0xAAAA) {
692  result = false;
693  std::cout << "QC ERROR: Trigger header marker wrong" << std::endl;
694  }
695 
696  // Check SIM flag in trigger mask
697  if (trigger->getTriggerMask()->getMonteCarloFlag() != fSim) {
698  result = false;
699  std::cout << "QC ERROR: Trigger Mask SIM flag wrong: " << trigger->getTriggerMask()->getMonteCarloFlag() << std::endl;
700  }
701 
702  // Check VTMod and Trig Types, compare to run header, if applicable
703  if (fCheckRun) {
704 #ifndef RAWRUN_IS_NOT_IMPLEMENTED
705  if (trigger->getTriggerMask()->getTrigMod() != fRun.getVTMod()) {
706  result = false;
707  std::cout << "QC ERROR: Trigger Mask Trigger Mod not consistent with VTMod in run header" << std::endl;
708  }
709  if ((trigger->getTriggerMask()->getTrigMask_Low() != fRun.getValidTriggerTypesLow())
710  || (trigger->getTriggerMask()->getTrigMask_High() != fRun.getValidTriggerTypesHigh())
711  || (trigger->getTriggerMask()->getTrigMask_High2() != fRun.getValidTriggerTypesHigh2())) {
712  result = false;
713  std::cout << "QC ERROR: Trigger mask trigger types not consistent with run header" << std::endl;
714  }
715 #endif
716  } else {
717 
718 
719  } // if fCheckRun
720 
721  return result;
722 } // checkTriggerBlock
723 
724 
725 /**
726  * Helper to perform checks on the DataBlock.
727  * @param data The data block to check
728  * @param idata The data block number, used only for printouts
729  */
731  bool result = true;
732  std::cout << "Check data block" << std::endl;
733 
734  // Check version, ID, etc are non-zero
735  if (data->getVersion() == 0) {
736  result = false;
737  std::cout << "QC ERROR: Datablock " << idata << " version number is zero (0)" << std::endl;
738  }
739  /*if (data->getBuffId() == 0) {
740  result = false;
741  std::cout << "QC ERROR: Datablock " << idata << " buffer node ID is zero (0)" << std::endl;
742  }*/
743 
744  // Check trigger number
745  if (data->getTrigNum() != fTrigger) {
746  result = false;
747  std::cout << "QC ERROR: Datablock " << idata << " trigger number wrong:"
748  << fTrigger << " vs " << data->getTrigNum() << std::endl;
749  }
750 
751  // Check SIM flag
752  if (data->getMonteCarloFlag() != fSim) {
753  result = false;
754  std::cout << "QC ERROR: Datablock " << idata << " SIM flag wrong" << std::endl;
755  }
756 
757  // Check 0xDABC marker
758  if (data->getMarker() != 0xDABC) {
759  result = false;
760  std::cout << "QC ERROR: Datablock " << idata << " 0xDABC marker wrong" << std::endl;
761  }
762 
763  // Check CRC checksum
764  if (data->isCRCCalculationUsed()) {
765  if (data->calculateCheckSum(0) != 0) {
766  result = false;
767  std::cout << "QC ERROR: Datablock " << idata << " CRC checksum wrong" << std::endl;
768  }
769  }
770 
771  return result;
772 } // checkDataBlock
773 
774 
775 /**
776  * Helper to perform checks on the MicroSlice.
777  * @param micro The MicroSlice to check
778  * @param idata The data block the MicroSlice belongs to, used only
779  * in printouts
780  * @param imicrob The MicroBlock the MicroSlice belongs to, used only
781  * in printouts
782  */
783 bool QualityCheck::checkMicroSlice(daqdataformats::RawMicroSlice* micro, uint32_t idata, uint32_t imicrob) {
784  bool result = true;
785  std::cout << "Check MicroSlice" << std::endl;
786 
787  // Check SIM flag
788  if (micro->getMonteCarloFlag() != fSim) {
789  result = false;
790  std::cout << "QC ERROR: Datablock " << idata << ", Microblock " << imicrob << " SIM flag wrong" << std::endl;
791  }
792 
793  // Check the DP flag
794  bool dp = micro->getDataPresent();
795  uint32_t nnano = micro->getNumNanoSlices();
796  if ((dp && nnano == 0) ||
797  (!dp && nnano != 0)) {
798  result = false;
799  std::cout << "QC ERROR: Datablock " << idata << ", Microblock " << imicrob << " DP flag wrong via num NanoSlices" << std::endl;
800  }
801 
802  if ((dp && micro->getByteCount() <= 8) || (!dp && micro->getByteCount() > 8)) {
803  result = false;
804  std::cout << "QC ERROR: Datablock " << idata << ", Microblock " << imicrob << " DP flag wrong via header byte count" << std::endl;
805  }
806 
807  return result;
808 } // checkMicroSlice
809 
810 
811 /**
812  * Helper to perform checks on the NanoSlice.
813  * @param nano The NanoSlice to check.
814  */
816  bool result = true;
817  std::cout << "Check NanoSlice" << std::endl;
818 
819  // Check the DP flag
820  bool dp = nano->getHeader()->getDataPresent();
821  if ((dp && nano->getPulseHeight() == 0) || (!dp && nano->getPulseHeight() != 0)) {
822  result = false;
823  std::cout << "QC ERROR: Nanoslice DP flag wrong: " << dp << ", " << nano->getPulseHeight() << std::endl;
824  }
825 
826  // Check the FEB Status against SIM flag
827  uint32_t stat = nano->getHeader()->getFEBStatus();
828 
829  if ((stat <= 0x3F && fSim) || (stat >= 0x40 && !fSim)) {
830  result = false;
831  std::cout << "QC ERROR: Nanoslice 'SIM flag' wrong:" << stat << " vs " << fSim << std::endl;
832  }
833 
834  return result;
835 } // checkNanoSlice
836 
837 
838 
IMPLEMENT_MAIN_STANDARD IMPLEMENT_MAIN_setBufferSource daqdataformats::RawNanoSliceHeader * getHeader() const
Get the NanoSlice header pointer.
Definition: RawNanoSlice.h:57
RawConfigurationSystemID * getSystemID(const uint32_t isystem)
bool checkNanoSlice(daqdataformats::RawNanoSlice *nano)
daqdataformats::RawEvent fEvent
Definition: QualityCheck.h:53
bool checkEventHeaderTail(daqdataformats::RawEventHeader *header, daqdataformats::RawEventTail *tail)
uint32_t getNumNanoSlices() const
Get current Hit Probability (for a microslice generation)
bool checkTriggerBlock(daqdataformats::RawTrigger *trigger)
Definition: config.py:1
bool checkDataBlock(daqdataformats::RawDataBlock *data, uint32_t idata)
uint64_t fEventCounter
Definition: QualityCheck.h:65
bool checkEvent(daqdataformats::RawEvent &event)
bool checkRunHeaderTail(daqdataformats::RawRunHeader *header, daqdataformats::RawRunHeader *tail)
Class to hold the data from the global trigger in the correct format.
Definition: RawTrigger.h:40
const XML_Char const XML_Char * data
Definition: expat.h:268
bool checkConfigBlock(daqdataformats::RawConfigurationBlock *config)
bool setFloatingNanoSlice(const uint32_t inano) const
Set the SIM flag.
Definition: run.py:1
OStream cout
Definition: OStream.cxx:6
uint32_t getByteCount() const
Get the Data Present bit of the Header.
bool checkRun(daqdataformats::RawRun &run)
Class to hold the MicroSlice data.
Definition: RawMicroSlice.h:48
bool checkMicroSlice(daqdataformats::RawMicroSlice *micro, uint32_t idata, uint32_t imicro)
bool getMonteCarloFlag() const
Get the Data Present bit of the Header.
def tail(path, window=20)
Definition: log_trawl.py:24
daqdataformats::RawRun fRun
Definition: QualityCheck.h:56
bool getDataPresent() const
Get Floating NanoSlice.
daqdataformats::RawNanoSlice * getFloatingNanoSlice() const
Get the MicroSlice Timing Marker.