artdaq_demo  3.12.07
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  fragmentHandles = evt.getMany<std::vector<artdaq::Fragment>>();
121 
122  for (const auto& handle : fragmentHandles)
123  {
124  if (!handle.isValid() || handle->empty())
125  {
126  continue;
127  }
128 
129  if (handle->front().type() == artdaq::Fragment::ContainerFragmentType)
130  {
131  for (const auto& cont : *handle)
132  {
133  artdaq::ContainerFragment contf(cont);
134  if (contf.fragment_type() != demo::FragmentType::TOY1 && contf.fragment_type() != demo::FragmentType::TOY2)
135  {
136  break;
137  }
138 
139  for (size_t ii = 0; ii < contf.block_count(); ++ii)
140  {
141  containerFragments.push_back(contf[ii]);
142  fragments.push_back(*containerFragments.back());
143  }
144  }
145  }
146  else
147  {
148  if (handle->front().type() == demo::FragmentType::TOY1 || handle->front().type() == demo::FragmentType::TOY2)
149  {
150  for (auto frag : *handle)
151  {
152  fragments.emplace_back(frag);
153  }
154  }
155  }
156  }
157 
158  // look for raw Toy data
159  TLOG(TLVL_INFO) << "Run " << evt.run() << ", subrun " << evt.subRun() << ", event " << eventNumber << " has "
160  << fragments.size() << " fragment(s) of type TOY1 or TOY2";
161  fragment_counts_[fragments.size()]++;
162  event_count_++;
163 
164  for (const auto& frag : fragments)
165  {
166  ToyFragment bb(frag);
167 
168  TLOG(TLVL_INFO) << fragmentTypeToString(static_cast<demo::detail::FragmentType>(frag.type()))
169  << " fragment " << frag.fragmentID() << " w/ seqID " << frag.sequenceID() << " and timestamp "
170  << frag.timestamp() << " has total ADC counts = " << bb.total_adc_values()
171  << ", trig # = " << bb.hdr_trigger_number()
172  << ", dist_type = " << static_cast<int>(bb.hdr_distribution_type());
173 
174  if (frag.hasMetadata())
175  {
176  auto const* md = frag.metadata<ToyFragment::Metadata>();
177  TLOG(TLVL_DEBUG) << "Fragment metadata: " << std::showbase
178  << "Board serial number = " << md->board_serial_number
179  << ", sample bits = " << md->num_adc_bits
180  << " -> max ADC value = " << demo::ToyFragment::adc_range(static_cast<int>(md->num_adc_bits));
181  }
182 
183  if (num_adcs_to_write_ >= 0)
184  {
185  uint32_t numAdcs = num_adcs_to_write_;
186  if (num_adcs_to_write_ == 0)
187  {
188  numAdcs = bb.total_adc_values();
189  }
190  else if (static_cast<uint32_t>(num_adcs_to_write_) > bb.total_adc_values())
191  {
192  TLOG(TLVL_WARNING)
193  << "Asked for more ADC values to file than are in Fragment. Only writing what's here...";
194  numAdcs = bb.total_adc_values();
195  }
196  if (binary_mode_)
197  {
198  std::ofstream output(output_file_name_, std::ios::out | std::ios::app | std::ios::binary);
199  for (uint32_t i_adc = 0; i_adc < numAdcs; ++i_adc)
200  {
201  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)
202  }
203  output.close();
204  }
205  else
206  {
207  std::ofstream output(output_file_name_, std::ios::out | std::ios::app);
208  output << fragmentTypeToString(static_cast<demo::detail::FragmentType>(frag.type())) << "\t"
209  << frag.fragmentID();
210 
211  for (uint32_t i_adc = 0; i_adc < numAdcs; ++i_adc)
212  {
213  output << "\t" << std::to_string(*(bb.dataBeginADCs() + i_adc)); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
214  }
215  output << std::endl;
216  output.close();
217  }
218  }
219 
220  if (num_adcs_to_print_ >= 0)
221  {
222  uint32_t numAdcs = num_adcs_to_print_;
223  if (num_adcs_to_print_ == 0)
224  {
225  numAdcs = bb.total_adc_values();
226  }
227  else if (static_cast<uint32_t>(num_adcs_to_print_) > bb.total_adc_values())
228  {
229  TLOG(TLVL_WARNING)
230  << "Asked for more ADC values to file than are in Fragment. Only writing what's here...";
231  numAdcs = bb.total_adc_values();
232  }
233 
234  TLOG(TLVL_INFO) << "First " << numAdcs << " ADC values in the fragment:";
235  int rows = 1 + static_cast<int>((num_adcs_to_print_ - 1) / columns_to_display_on_screen_);
236  uint32_t adc_counter = 0;
237  for (int idx = 0; idx < rows; ++idx)
238  {
239  std::ostringstream o;
240  o << std::right;
241  o << std::setw(4) << std::setfill('.');
242  o << (idx * columns_to_display_on_screen_) << ": ";
243  for (uint32_t jdx = 0; jdx < columns_to_display_on_screen_; ++jdx)
244  {
245  if (adc_counter >= numAdcs)
246  {
247  break;
248  }
249  o << std::setw(6) << std::setfill(' ');
250  o << bb.adc_value(adc_counter);
251  ++adc_counter;
252  }
253  TLOG(TLVL_INFO) << o.str();
254  }
255  }
256  }
257 }
258 
259 void demo::ToyDump::endSubRun(art::SubRun const& sr)
260 {
261  auto limit_save = traceControl_rwp->limit_cnt_limit;
262  traceControl_rwp->limit_cnt_limit = 0;
263  TLOG(TLVL_INFO) << "ENDSUBRUN: Run " << sr.id().run() << ", Subrun " << sr.id().subRun() << " has " << event_count_ << " events.";
264  for (auto const& c : fragment_counts_)
265  {
266  TLOG(TLVL_INFO) << "ENDSUBRUN: There were " << c.second << " events with " << c.first << " TOY1 or TOY2 Fragments";
267  }
268  traceControl_rwp->limit_cnt_limit = limit_save;
269  fragment_counts_.clear();
270  event_count_ = 0;
271 }
272 
273 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) ...