artdaq_demo  v3_11_02
ToyDump_module.cc
1 // Class: ToyDump
3 // Module Type: analyzer
4 // File: ToyDump_module.cc
5 // Description: Prints out information about each event.
7 
8 #define TRACE_NAME "ToyDump"
9 
10 #include "art/Framework/Core/EDAnalyzer.h"
11 #include "art/Framework/Core/ModuleMacros.h"
12 #include "art/Framework/Principal/Event.h"
13 #include "art/Framework/Principal/Handle.h"
14 #include "art/Framework/Principal/SubRun.h"
15 #include "canvas/Utilities/Exception.h"
16 
17 #include "artdaq-core-demo/Overlays/FragmentType.hh"
18 #include "artdaq-core-demo/Overlays/ToyFragment.hh"
19 #include "artdaq-core/Data/ContainerFragment.hh"
20 #include "artdaq-core/Data/Fragment.hh"
21 
22 #include <algorithm>
23 #include <cassert>
24 #include <cmath>
25 #include <fstream>
26 #include <iomanip>
27 #include <iostream>
28 #include <map>
29 #include <vector>
30 
31 namespace demo {
32 class ToyDump;
33 } // namespace demo
34 
38 class demo::ToyDump : public art::EDAnalyzer
39 {
40 public:
54  explicit ToyDump(fhicl::ParameterSet const& pset);
55 
59  ~ToyDump() override;
60 
65  void analyze(art::Event const& evt) override;
66 
71  void endSubRun(art::SubRun const& sr) override;
72 
73 private:
74  ToyDump(ToyDump const&) = delete;
75  ToyDump(ToyDump&&) = delete;
76  ToyDump& operator=(ToyDump const&) = delete;
77  ToyDump& operator=(ToyDump&&) = delete;
78 
79  std::string raw_data_label_;
80  int num_adcs_to_write_;
81  int num_adcs_to_print_;
82  bool binary_mode_;
83  uint32_t columns_to_display_on_screen_;
84  std::string output_file_name_;
85 
86  std::map<size_t, size_t> fragment_counts_;
87  size_t event_count_{0};
88  art::EventNumber_t last_event_{0};
89 };
90 
91 demo::ToyDump::ToyDump(fhicl::ParameterSet const& pset)
92  : EDAnalyzer(pset)
93  , raw_data_label_(pset.get<std::string>("raw_data_label", "daq"))
94  , num_adcs_to_write_(pset.get<int>("num_adcs_to_write", 0))
95  , num_adcs_to_print_(pset.get<int>("num_adcs_to_print", 10))
96  , binary_mode_(pset.get<bool>("binary_mode", true))
97  , columns_to_display_on_screen_(pset.get<uint32_t>("columns_to_display_on_screen", 10))
98  , output_file_name_(pset.get<std::string>("output_file_name", "out.bin"))
99 {}
100 
101 demo::ToyDump::~ToyDump() = default;
102 
103 void demo::ToyDump::analyze(art::Event const& evt)
104 {
105  art::EventNumber_t eventNumber = evt.event();
106  if (last_event_ != 0 && last_event_ + 1 != eventNumber)
107  {
108  TLOG(TLVL_WARNING) << "Event ordering problem! Current event number " << eventNumber << " disagrees with predicted " << last_event_ + 1;
109  }
110  last_event_ = eventNumber;
111 
112  // ***********************
113  // *** Toy Fragments ***
114  // ***********************
115 
116  artdaq::Fragments fragments;
117  artdaq::FragmentPtrs containerFragments;
118 
119  std::vector<art::Handle<artdaq::Fragments>> fragmentHandles;
120 #if ART_HEX_VERSION < 0x30900
121  evt.getManyByType(fragmentHandles);
122 #else
123  fragmentHandles = evt.getMany<std::vector<artdaq::Fragment>>();
124 #endif
125 
126  for (const auto& handle : fragmentHandles)
127  {
128  if (!handle.isValid() || handle->empty())
129  {
130  continue;
131  }
132 
133  if (handle->front().type() == artdaq::Fragment::ContainerFragmentType)
134  {
135  for (const auto& cont : *handle)
136  {
137  artdaq::ContainerFragment contf(cont);
138  if (contf.fragment_type() != demo::FragmentType::TOY1 && contf.fragment_type() != demo::FragmentType::TOY2)
139  {
140  break;
141  }
142 
143  for (size_t ii = 0; ii < contf.block_count(); ++ii)
144  {
145  containerFragments.push_back(contf[ii]);
146  fragments.push_back(*containerFragments.back());
147  }
148  }
149  }
150  else
151  {
152  if (handle->front().type() == demo::FragmentType::TOY1 || handle->front().type() == demo::FragmentType::TOY2)
153  {
154  for (auto frag : *handle)
155  {
156  fragments.emplace_back(frag);
157  }
158  }
159  }
160  }
161 
162  // look for raw Toy data
163  TLOG(TLVL_INFO) << "Run " << evt.run() << ", subrun " << evt.subRun() << ", event " << eventNumber << " has "
164  << fragments.size() << " fragment(s) of type TOY1 or TOY2";
165  fragment_counts_[fragments.size()]++;
166  event_count_++;
167 
168  for (const auto& frag : fragments)
169  {
170  ToyFragment bb(frag);
171 
172  TLOG(TLVL_INFO) << fragmentTypeToString(static_cast<demo::detail::FragmentType>(frag.type()))
173  << " fragment " << frag.fragmentID() << " w/ seqID " << frag.sequenceID() << " and timestamp "
174  << frag.timestamp() << " has total ADC counts = " << bb.total_adc_values()
175  << ", trig # = " << bb.hdr_trigger_number()
176  << ", dist_type = " << static_cast<int>(bb.hdr_distribution_type());
177 
178  if (frag.hasMetadata())
179  {
180  auto const* md = frag.metadata<ToyFragment::Metadata>();
181  TLOG(TLVL_DEBUG) << "Fragment metadata: " << std::showbase
182  << "Board serial number = " << md->board_serial_number
183  << ", sample bits = " << md->num_adc_bits
184  << " -> max ADC value = " << demo::ToyFragment::adc_range(static_cast<int>(md->num_adc_bits));
185  }
186 
187  if (num_adcs_to_write_ >= 0)
188  {
189  uint32_t numAdcs = num_adcs_to_write_;
190  if (num_adcs_to_write_ == 0)
191  {
192  numAdcs = bb.total_adc_values();
193  }
194  else if (static_cast<uint32_t>(num_adcs_to_write_) > bb.total_adc_values())
195  {
196  TLOG(TLVL_WARNING)
197  << "Asked for more ADC values to file than are in Fragment. Only writing what's here...";
198  numAdcs = bb.total_adc_values();
199  }
200  if (binary_mode_)
201  {
202  std::ofstream output(output_file_name_, std::ios::out | std::ios::app | std::ios::binary);
203  for (uint32_t i_adc = 0; i_adc < numAdcs; ++i_adc)
204  {
205  output.write(reinterpret_cast<const char*>(bb.dataBeginADCs() + i_adc), sizeof(ToyFragment::adc_t)); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic,cppcoreguidelines-pro-type-reinterpret-cast)
206  }
207  output.close();
208  }
209  else
210  {
211  std::ofstream output(output_file_name_, std::ios::out | std::ios::app);
212  output << fragmentTypeToString(static_cast<demo::detail::FragmentType>(frag.type())) << "\t"
213  << frag.fragmentID();
214 
215  for (uint32_t i_adc = 0; i_adc < numAdcs; ++i_adc)
216  {
217  output << "\t" << std::to_string(*(bb.dataBeginADCs() + i_adc)); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
218  }
219  output << std::endl;
220  output.close();
221  }
222  }
223 
224  if (num_adcs_to_print_ >= 0)
225  {
226  uint32_t numAdcs = num_adcs_to_print_;
227  if (num_adcs_to_print_ == 0)
228  {
229  numAdcs = bb.total_adc_values();
230  }
231  else if (static_cast<uint32_t>(num_adcs_to_print_) > bb.total_adc_values())
232  {
233  TLOG(TLVL_WARNING)
234  << "Asked for more ADC values to file than are in Fragment. Only writing what's here...";
235  numAdcs = bb.total_adc_values();
236  }
237 
238  TLOG(TLVL_INFO) << "First " << numAdcs << " ADC values in the fragment:";
239  int rows = 1 + static_cast<int>((num_adcs_to_print_ - 1) / columns_to_display_on_screen_);
240  uint32_t adc_counter = 0;
241  for (int idx = 0; idx < rows; ++idx)
242  {
243  std::ostringstream o;
244  o << std::right;
245  o << std::setw(4) << std::setfill('.');
246  o << (idx * columns_to_display_on_screen_) << ": ";
247  for (uint32_t jdx = 0; jdx < columns_to_display_on_screen_; ++jdx)
248  {
249  if (adc_counter >= numAdcs)
250  {
251  break;
252  }
253  o << std::setw(6) << std::setfill(' ');
254  o << bb.adc_value(adc_counter);
255  ++adc_counter;
256  }
257  TLOG(TLVL_INFO) << o.str();
258  }
259  }
260  }
261 }
262 
263 void demo::ToyDump::endSubRun(art::SubRun const& sr)
264 {
265  auto limit_save = traceControl_rwp->limit_cnt_limit;
266  traceControl_rwp->limit_cnt_limit = 0;
267  TLOG(TLVL_INFO) << "ENDSUBRUN: Run " << sr.id().run() << ", Subrun " << sr.id().subRun() << " has " << event_count_ << " events.";
268  for (auto const& c : fragment_counts_)
269  {
270  TLOG(TLVL_INFO) << "ENDSUBRUN: There were " << c.second << " events with " << c.first << " TOY1 or TOY2 Fragments";
271  }
272  traceControl_rwp->limit_cnt_limit = limit_save;
273  fragment_counts_.clear();
274  event_count_ = 0;
275 }
276 
277 DEFINE_ART_MODULE(demo::ToyDump) // NOLINT(performance-unnecessary-value-param)
void endSubRun(art::SubRun const &sr) override
Print summary information from a SubRun.
ToyDump(fhicl::ParameterSet const &pset)
ToyDump Constructor.
~ToyDump() override
ToyDump Destructor.
An art::EDAnalyzer module designed to display the data from demo::ToyFragment objects.
void analyze(art::Event const &evt) override
Analyze an event. Called by art for each event in run (based on command line options) ...