artdaq_demo  v3_11_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/FragmentType.hh"
15 #include "artdaq-core-demo/Overlays/ToyFragment.hh"
16 #include "artdaq-core/Data/ContainerFragment.hh"
17 #include "artdaq-core/Data/Fragment.hh"
18 
19 #include "TRACE/tracemf.h" // TLOG
20 #define TRACE_NAME "CheckIntegrity"
21 
22 #include <algorithm>
23 #include <cassert>
24 #include <cmath>
25 #include <fstream>
26 #include <iomanip>
27 #include <iostream>
28 #include <vector>
29 
30 namespace demo {
31 class CheckIntegrity;
32 } // namespace demo
33 
37 class demo::CheckIntegrity : public art::EDAnalyzer
38 {
39 public:
49  explicit CheckIntegrity(fhicl::ParameterSet const& pset);
50 
54  ~CheckIntegrity() override = default;
55 
60  void analyze(art::Event const& evt) override;
61 
62 private:
63  CheckIntegrity(CheckIntegrity const&) = delete;
64  CheckIntegrity(CheckIntegrity&&) = delete;
65  CheckIntegrity& operator=(CheckIntegrity const&) = delete;
66  CheckIntegrity& operator=(CheckIntegrity&&) = delete;
67 
68  std::string raw_data_label_;
69  bool exception_on_integrity_failure_;
70 };
71 
72 demo::CheckIntegrity::CheckIntegrity(fhicl::ParameterSet const& pset)
73  : EDAnalyzer(pset)
74  , raw_data_label_(pset.get<std::string>("raw_data_label", "daq"))
75  , exception_on_integrity_failure_(pset.get<bool>("exception_on_integrity_failure", false))
76 {}
77 
78 void demo::CheckIntegrity::analyze(art::Event const& evt)
79 {
80  artdaq::Fragments fragments;
81  artdaq::FragmentPtrs containerFragments;
82 
83  std::vector<art::Handle<artdaq::Fragments>> fragmentHandles;
84 #if ART_HEX_VERSION < 0x30900
85  evt.getManyByType(fragmentHandles);
86 #else
87  fragmentHandles = evt.getMany<std::vector<artdaq::Fragment>>();
88 #endif
89 
90  for (const auto& handle : fragmentHandles)
91  {
92  if (!handle.isValid() || handle->empty())
93  {
94  continue;
95  }
96 
97  if (handle->front().type() == artdaq::Fragment::ContainerFragmentType)
98  {
99  for (const auto& cont : *handle)
100  {
101  artdaq::ContainerFragment contf(cont);
102  if (contf.fragment_type() != demo::FragmentType::TOY1 && contf.fragment_type() != demo::FragmentType::TOY2)
103  {
104  break;
105  }
106 
107  for (size_t ii = 0; ii < contf.block_count(); ++ii)
108  {
109  containerFragments.push_back(contf[ii]);
110  fragments.push_back(*containerFragments.back());
111  }
112  }
113  }
114  else
115  {
116  if (handle->front().type() == demo::FragmentType::TOY1 || handle->front().type() == demo::FragmentType::TOY2)
117  {
118  for (auto frag : *handle)
119  {
120  fragments.emplace_back(frag);
121  }
122  }
123  }
124  }
125 
126  TLOG(TLVL_DEBUG) << "Run " << evt.run() << ", subrun " << evt.subRun() << ", event " << evt.event() << " has "
127  << fragments.size() << " fragment(s) of type TOY1 or TOY2";
128 
129  bool err = false;
130  for (const auto& frag : fragments)
131  {
132  // These methods take significantly more time when processing non-CurrentVersion Fragments, so cache them here
133  ToyFragment bb(frag);
134  auto dist_type = bb.hdr_distribution_type();
135 
136  if (bb.hdr_event_size() * sizeof(ToyFragment::Header::data_t) !=
137  frag.dataSize() * sizeof(artdaq::RawDataType))
138  {
139  TLOG(TLVL_ERROR) << "Error: in run " << evt.run() << ", subrun " << evt.subRun() << ", event "
140  << evt.event() << ", seqID " << frag.sequenceID() << ", fragID " << frag.fragmentID()
141  << ": Size mismatch!"
142  << " ToyFragment Header reports size of "
143  << bb.hdr_event_size() * sizeof(ToyFragment::Header::data_t)
144  << " bytes, but Fragment reports size of "
145  << frag.dataSize() * sizeof(artdaq::RawDataType) << " bytes.";
146 
147  if (exception_on_integrity_failure_)
148  {
149  throw cet::exception("CheckIntegrity")
150  << "Error: in run " << evt.run() << ", subrun " << evt.subRun() << ", event " << evt.event()
151  << ", seqID " << frag.sequenceID() << ", fragID " << frag.fragmentID() << ": Size mismatch!"
152  << " ToyFragment Header reports size of "
153  << bb.hdr_event_size() * sizeof(ToyFragment::Header::data_t)
154  << " bytes, but Fragment reports size of " << frag.dataSize() * sizeof(artdaq::RawDataType)
155  << " bytes.";
156  }
157  continue;
158  }
159 
160  if ((frag.size() - frag.headerSizeWords() - frag.dataSize()) * sizeof(artdaq::RawDataType) !=
161  sizeof(ToyFragment::Metadata))
162  {
163  TLOG(TLVL_ERROR) << "Error: in run " << evt.run() << ", subrun " << evt.subRun() << ", event "
164  << evt.event() << ", seqID " << frag.sequenceID() << ", fragID " << frag.fragmentID()
165  << ": Metadata error!"
166  << " ToyFragment metadata size should be " << sizeof(ToyFragment::Metadata)
167  << " bytes, but Fragment reports size of "
168  << (frag.size() - frag.headerSizeWords() - frag.dataSize()) *
169  sizeof(artdaq::RawDataType)
170  << " bytes.";
171  if (exception_on_integrity_failure_)
172  {
173  throw cet::exception("CheckIntegrity")
174  << "Error: in run " << evt.run() << ", subrun " << evt.subRun() << ", event " << evt.event()
175  << ", seqID " << frag.sequenceID() << ", fragID " << frag.fragmentID() << ": Metadata error!"
176  << " ToyFragment metadata size should be " << sizeof(ToyFragment::Metadata)
177  << " bytes, but Fragment reports size of "
178  << (frag.size() - frag.headerSizeWords() - frag.dataSize()) * sizeof(artdaq::RawDataType)
179  << " bytes.";
180  }
181  continue;
182  }
183 
184  {
185  auto adc_iter = bb.dataBeginADCs();
186  auto adc_end = bb.dataEndADCs();
187  ToyFragment::adc_t expected_adc = 1;
188 
189  for (; adc_iter != adc_end; adc_iter++, expected_adc++)
190  {
191  if (expected_adc > demo::ToyFragment::adc_range(frag.metadata<ToyFragment::Metadata>()->num_adc_bits))
192  {
193  expected_adc = 0;
194  }
195 
196  // ELF 7/10/18: Distribution type 2 is the monotonically-increasing one
197  if (dist_type == 2 && *adc_iter != expected_adc)
198  {
199  TLOG(TLVL_ERROR) << "Error: in run " << evt.run() << ", subrun " << evt.subRun() << ", event "
200  << evt.event() << ", seqID " << frag.sequenceID() << ", fragID "
201  << frag.fragmentID() << ": expected an ADC value of " << expected_adc << ", got "
202  << *adc_iter;
203  err = true;
204  if (exception_on_integrity_failure_)
205  {
206  throw cet::exception("CheckIntegrity")
207  << "Error: in run " << evt.run() << ", subrun " << evt.subRun() << ", event " << evt.event()
208  << ", seqID " << frag.sequenceID() << ", fragID " << frag.fragmentID()
209  << ": expected an ADC value of " << expected_adc << ", got " << *adc_iter;
210  }
211  break;
212  }
213 
214  // ELF 7/10/18: As of now, distribution types 3 and 4 are uninitialized, and can therefore produce
215  // out-of-range counts.
216  if (bb.hdr_distribution_type() < 3 &&
217  *adc_iter > demo::ToyFragment::adc_range(frag.metadata<ToyFragment::Metadata>()->num_adc_bits))
218  {
219  TLOG(TLVL_ERROR) << "Error: in run " << evt.run() << ", subrun " << evt.subRun() << ", event "
220  << evt.event() << ", seqID " << frag.sequenceID() << ", fragID "
221  << frag.fragmentID() << ": " << *adc_iter
222  << " is out-of-range for this Fragment type";
223  err = true;
224  if (exception_on_integrity_failure_)
225  {
226  throw cet::exception("CheckIntegrity")
227  << "Error: in run " << evt.run() << ", subrun " << evt.subRun() << ", event " << evt.event()
228  << ", seqID " << frag.sequenceID() << ", fragID " << frag.fragmentID() << ": " << *adc_iter
229  << " is out-of-range for this Fragment type";
230  }
231  break;
232  }
233  }
234  }
235  }
236  if (!err)
237  {
238  TLOG(TLVL_DEBUG) << "In run " << evt.run() << ", subrun " << evt.subRun() << ", event " << evt.event()
239  << ", everything is fine";
240  }
241 }
242 
243 DEFINE_ART_MODULE(demo::CheckIntegrity) // NOLINT(performance-unnecessary-value-param)
~CheckIntegrity() override=default
Default destructor.
void analyze(art::Event const &evt) override
Analyze an event. Called by art for each event in run (based on command line options) ...
Demonstration art::EDAnalyzer which checks that all ToyFragment ADC counts are in the defined range...
CheckIntegrity(fhicl::ParameterSet const &pset)
CheckIntegrity Constructor.