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