artdaq_demo  v3_09_04
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:
48  explicit CheckIntegrity(fhicl::ParameterSet const& pset);
49 
53  ~CheckIntegrity() override = default;
54 
59  void analyze(art::Event const& evt) override;
60 
61 private:
62  CheckIntegrity(CheckIntegrity const&) = delete;
63  CheckIntegrity(CheckIntegrity&&) = delete;
64  CheckIntegrity& operator=(CheckIntegrity const&) = delete;
65  CheckIntegrity& operator=(CheckIntegrity&&) = delete;
66 
67  std::string raw_data_label_;
68 };
69 
70 demo::CheckIntegrity::CheckIntegrity(fhicl::ParameterSet const& pset)
71  : EDAnalyzer(pset), raw_data_label_(pset.get<std::string>("raw_data_label"))
72 {}
73 
74 void demo::CheckIntegrity::analyze(art::Event const& evt)
75 {
76  artdaq::Fragments fragments;
77  artdaq::FragmentPtrs containerFragments;
78 
79  std::vector<art::Handle<artdaq::Fragments>> fragmentHandles;
80  evt.getManyByType(fragmentHandles);
81 
82  for (const auto& handle : fragmentHandles)
83  {
84  if (!handle.isValid() || handle->empty())
85  {
86  continue;
87  }
88 
89  if (handle->front().type() == artdaq::Fragment::ContainerFragmentType)
90  {
91  for (const auto& cont : *handle)
92  {
93  artdaq::ContainerFragment contf(cont);
94  if (contf.fragment_type() != demo::FragmentType::TOY1 && contf.fragment_type() != demo::FragmentType::TOY2)
95  {
96  break;
97  }
98 
99  for (size_t ii = 0; ii < contf.block_count(); ++ii)
100  {
101  containerFragments.push_back(contf[ii]);
102  fragments.push_back(*containerFragments.back());
103  }
104  }
105  }
106  else
107  {
108  if (handle->front().type() == demo::FragmentType::TOY1 || handle->front().type() == demo::FragmentType::TOY2)
109  {
110  for (auto frag : *handle)
111  {
112  fragments.emplace_back(frag);
113  }
114  }
115  }
116  }
117 
118  TLOG(TLVL_DEBUG) << "Run " << evt.run() << ", subrun " << evt.subRun() << ", event " << evt.event() << " has "
119  << fragments.size() << " fragment(s) of type TOY1 or TOY2";
120 
121  bool err = false;
122  for (const auto& frag : fragments)
123  {
124  ToyFragment bb(frag);
125 
126  if (bb.hdr_event_size() * sizeof(ToyFragment::Header::data_t) !=
127  frag.dataSize() * sizeof(artdaq::RawDataType))
128  {
129  TLOG(TLVL_ERROR) << "Error: in run " << evt.run() << ", subrun " << evt.subRun() << ", event "
130  << evt.event() << ", seqID " << frag.sequenceID() << ", fragID " << frag.fragmentID()
131  << ": Size mismatch!"
132  << " ToyFragment Header reports size of "
133  << bb.hdr_event_size() * sizeof(ToyFragment::Header::data_t)
134  << " bytes, Fragment report size of " << frag.dataSize() * sizeof(artdaq::RawDataType)
135  << " bytes.";
136  continue;
137  }
138 
139  {
140  auto adc_iter = bb.dataBeginADCs();
141  ToyFragment::adc_t expected_adc = 1;
142 
143  for (; adc_iter != bb.dataEndADCs(); adc_iter++, expected_adc++)
144  {
145  if (expected_adc > demo::ToyFragment::adc_range(frag.metadata<ToyFragment::Metadata>()->num_adc_bits))
146  {
147  expected_adc = 0;
148  }
149 
150  // ELF 7/10/18: Distribution type 2 is the monotonically-increasing one
151  if (bb.hdr_distribution_type() == 2 && *adc_iter != expected_adc)
152  {
153  TLOG(TLVL_ERROR) << "Error: in run " << evt.run() << ", subrun " << evt.subRun() << ", event "
154  << evt.event() << ", seqID " << frag.sequenceID() << ", fragID "
155  << frag.fragmentID() << ": expected an ADC value of " << expected_adc << ", got "
156  << *adc_iter;
157  err = true;
158  break;
159  }
160 
161  // ELF 7/10/18: As of now, distribution types 3 and 4 are uninitialized, and can therefore produce
162  // out-of-range counts.
163  if (bb.hdr_distribution_type() < 3 &&
164  *adc_iter > demo::ToyFragment::adc_range(frag.metadata<ToyFragment::Metadata>()->num_adc_bits))
165  {
166  TLOG(TLVL_ERROR) << "Error: in run " << evt.run() << ", subrun " << evt.subRun() << ", event "
167  << evt.event() << ", seqID " << frag.sequenceID() << ", fragID "
168  << frag.fragmentID() << ": " << *adc_iter
169  << " is out-of-range for this Fragment type";
170  err = true;
171  break;
172  }
173  }
174  }
175  }
176  if (!err)
177  {
178  TLOG(TLVL_DEBUG) << "In run " << evt.run() << ", subrun " << evt.subRun() << ", event " << evt.event()
179  << ", everything is fine";
180  }
181 }
182 
183 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.