artdaq_demo  v3_04_00
CheckIntegrity_module.cc
1 // Class: CheckIntegrity
3 // Module Type: analyzer
4 // File: CheckIntegrity_module.cc
5 // Description: Prints out information about each event.
7 
8 #include "art/Framework/Core/EDAnalyzer.h"
9 #include "art/Framework/Core/ModuleMacros.h"
10 #include "art/Framework/Principal/Event.h"
11 #include "art/Framework/Principal/Handle.h"
12 #include "canvas/Utilities/Exception.h"
13 
14 #include "artdaq-core-demo/Overlays/ToyFragment.hh"
15 #include "artdaq-core/Data/ContainerFragment.hh"
16 #include "artdaq-core/Data/Fragment.hh"
17 
18 #include "tracemf.h" // TLOG
19 #define TRACE_NAME "CheckIntegrity"
20 
21 #include <algorithm>
22 #include <cassert>
23 #include <cmath>
24 #include <fstream>
25 #include <iomanip>
26 #include <vector>
27 #include <iostream>
28 
29 namespace demo
30 {
31  class CheckIntegrity;
32 }
33 
37 class demo::CheckIntegrity : public art::EDAnalyzer
38 {
39 public:
48  explicit CheckIntegrity(fhicl::ParameterSet const& pset);
49 
53  virtual ~CheckIntegrity() = default;
54 
59  virtual void analyze(art::Event const& evt);
60 
61 private:
62  std::string raw_data_label_;
63 };
64 
65 
66 demo::CheckIntegrity::CheckIntegrity(fhicl::ParameterSet const& pset)
67  : EDAnalyzer(pset)
68  , raw_data_label_(pset.get<std::string>("raw_data_label"))
69 {}
70 
71 void demo::CheckIntegrity::analyze(art::Event const& evt)
72 {
73 
74 
75  artdaq::Fragments fragments;
76  artdaq::FragmentPtrs containerFragments;
77  std::vector<std::string> fragment_type_labels{ "TOY1", "TOY2", "ContainerTOY1", "ContainerTOY2" };
78 
79  for (auto label : fragment_type_labels)
80  {
81  art::Handle<artdaq::Fragments> fragments_with_label;
82 
83  evt.getByLabel(raw_data_label_, label, fragments_with_label);
84  if (!fragments_with_label.isValid()) continue;
85 
86  if (label == "Container" || label == "ContainerTOY1" || label == "ContainerTOY2")
87  {
88  for (auto cont : *fragments_with_label)
89  {
90  artdaq::ContainerFragment contf(cont);
91  for (size_t ii = 0; ii < contf.block_count(); ++ii)
92  {
93  containerFragments.push_back(contf[ii]);
94  fragments.push_back(*containerFragments.back());
95  }
96  }
97  }
98  else
99  {
100  for (auto frag : *fragments_with_label)
101  {
102  fragments.emplace_back(frag);
103  }
104  }
105  }
106 
107  TLOG(TLVL_INFO) << "Run " << evt.run() << ", subrun " << evt.subRun()
108  << ", event " << evt.event() << " has " << fragments.size()
109  << " fragment(s) of type TOY1 or TOY2";
110 
111  bool err = false;
112  for (const auto& frag : fragments)
113  {
114  ToyFragment bb(frag);
115 
116  if (bb.hdr_event_size() * sizeof(ToyFragment::Header::data_t) != frag.dataSize() * sizeof(artdaq::RawDataType))
117  {
118  TLOG(TLVL_ERROR) << "Error: in run " << evt.run() << ", subrun " << evt.subRun() <<
119  ", event " << evt.event() << ", seqID " << frag.sequenceID() <<
120  ", fragID " << frag.fragmentID() << ": Size mismatch!" <<
121  " ToyFragment Header reports size of " << bb.hdr_event_size() * sizeof(ToyFragment::Header::data_t) << " bytes, Fragment report size of " << frag.dataSize() * sizeof(artdaq::RawDataType) << " bytes.";
122  continue;
123  }
124 
125 
126  {
127  auto adc_iter = bb.dataBeginADCs();
128  ToyFragment::adc_t expected_adc = 1;
129 
130  for (; adc_iter != bb.dataEndADCs(); adc_iter++, expected_adc++)
131  {
132  if (expected_adc > bb.adc_range(frag.metadata<ToyFragment::Metadata>()->num_adc_bits)) expected_adc = 0;
133 
134  // ELF 7/10/18: Distribution type 2 is the monotonically-increasing one
135  if (bb.hdr_distribution_type() == 2 && *adc_iter != expected_adc)
136  {
137  TLOG(TLVL_ERROR) << "Error: in run " << evt.run() << ", subrun " << evt.subRun() <<
138  ", event " << evt.event() << ", seqID " << frag.sequenceID() <<
139  ", fragID " << frag.fragmentID() << ": expected an ADC value of " << expected_adc <<
140  ", got " << *adc_iter;
141  err = true;
142  break;
143  }
144 
145  // ELF 7/10/18: As of now, distribution types 3 and 4 are uninitialized, and can therefore produce out-of-range counts.
146  if (bb.hdr_distribution_type() < 3 && *adc_iter > bb.adc_range(frag.metadata<ToyFragment::Metadata>()->num_adc_bits))
147  {
148  TLOG(TLVL_ERROR) << "Error: in run " << evt.run() << ", subrun " << evt.subRun() <<
149  ", event " << evt.event() << ", seqID " << frag.sequenceID() <<
150  ", fragID " << frag.fragmentID() << ": " << *adc_iter << " is out-of-range for this Fragment type";
151  err = true;
152  break;
153  }
154  }
155 
156  }
157  }
158  if (!err) {
159  TLOG(TLVL_DEBUG) << "In run " << evt.run() << ", subrun " << evt.subRun() <<
160  ", event " << evt.event() << ", everything is fine";
161  }
162 }
163 
164 DEFINE_ART_MODULE(demo::CheckIntegrity)
std::vector< Fragment > Fragments
virtual void analyze(art::Event const &evt)
Analyze an event. Called by art for each event in run (based on command line options) ...
virtual ~CheckIntegrity()=default
Default destructor.
Header::event_size_t hdr_event_size() const
uint8_t hdr_distribution_type() const
adc_t const * dataBeginADCs() const
static size_t adc_range(int daq_adc_bits)
Metadata::count_t block_count() const
detail::RawFragmentHeader::RawDataType RawDataType
std::list< FragmentPtr > FragmentPtrs
Demonstration art::EDAnalyzer which checks that all ToyFragment ADC counts are in the defined range...
CheckIntegrity(fhicl::ParameterSet const &pset)
CheckIntegrity Constructor.
adc_t const * dataEndADCs() const