1 #include "TRACE/tracemf.h"
2 #define TRACE_NAME "WFViewer"
4 #include "art/Framework/Core/EDAnalyzer.h"
5 #include "art/Framework/Core/ModuleMacros.h"
6 #include "art/Framework/Principal/Event.h"
7 #include "art/Framework/Principal/Handle.h"
8 #include "art/Framework/Principal/Run.h"
9 #include "canvas/Utilities/InputTag.h"
10 #include "cetlib_except/exception.h"
12 #include "artdaq-core/Data/ContainerFragment.hh"
13 #include "artdaq-core/Data/Fragment.hh"
15 #include "artdaq-core-demo/Overlays/FragmentType.hh"
16 #include "artdaq-core-demo/Overlays/ToyFragment.hh"
23 #include <TRootCanvas.h>
28 #include <initializer_list>
34 #include <unordered_map>
38 #define TRACE_NAME "WFViewer"
63 explicit WFViewer(fhicl::ParameterSet
const& p);
74 void analyze(art::Event
const& e)
override;
80 void beginRun(art::Run
const& )
override;
88 TCanvas* histogram_canvas_;
89 TCanvas* graph_canvas_;
90 std::vector<Double_t> x_;
92 bool digital_sum_only_;
93 art::RunNumber_t current_run_;
95 size_t max_num_x_plots_;
96 size_t max_num_y_plots_;
97 std::size_t num_x_plots_;
98 std::size_t num_y_plots_;
100 std::string raw_data_label_;
102 std::unordered_map<artdaq::Fragment::fragment_id_t, TGraph*> graphs_;
103 std::unordered_map<artdaq::Fragment::fragment_id_t, TH1D*> histograms_;
105 std::map<artdaq::Fragment::fragment_id_t, std::size_t> id_to_index_;
106 std::string outputFileName_;
118 : art::EDAnalyzer(ps)
119 , prescale_(ps.get<int>(
"prescale"))
120 , digital_sum_only_(ps.get<bool>(
"digital_sum_only", false))
122 , max_num_x_plots_(ps.get<std::size_t>(
"num_x_plots", std::numeric_limits<std::size_t>::max()))
123 , max_num_y_plots_(ps.get<std::size_t>(
"num_y_plots", std::numeric_limits<std::size_t>::max()))
126 , raw_data_label_(ps.get<std::string>(
"raw_data_label",
"daq"))
129 , outputFileName_(ps.get<std::string>(
"fileName",
"artdaqdemo_onmon.root"))
130 , writeOutput_(ps.get<bool>(
"write_to_file", false))
132 , dynamicMode_(ps.get<bool>(
"dynamic_mode", true))
134 gStyle->SetOptStat(
"irm");
135 gStyle->SetMarkerStyle(22);
136 gStyle->SetMarkerColor(4);
138 if (ps.has_key(
"fragment_ids"))
140 auto fragment_ids = ps.get<std::vector<artdaq::Fragment::fragment_id_t>>(
"fragment_ids");
141 for (
auto&
id : fragment_ids)
143 auto index = id_to_index_.size();
144 id_to_index_[id] = index;
149 void demo::WFViewer::getXYDims_()
152 if (max_num_x_plots_ == 0) max_num_x_plots_ = std::numeric_limits<size_t>::max();
153 if (max_num_y_plots_ == 0) max_num_y_plots_ = std::numeric_limits<size_t>::max();
155 num_x_plots_ = num_y_plots_ =
static_cast<std::size_t
>(ceil(sqrt(id_to_index_.size())));
158 if (id_to_index_.size() > max_num_x_plots_ && id_to_index_.size() > max_num_x_plots_ * max_num_y_plots_)
160 num_x_plots_ = max_num_x_plots_;
161 num_y_plots_ = max_num_y_plots_;
162 auto max = num_x_plots_ * num_y_plots_;
163 auto it = id_to_index_.begin();
164 while (it != id_to_index_.end())
166 if (it->second >= max) { it = id_to_index_.erase(it); }
176 if (max_num_x_plots_ >= 4 && max_num_y_plots_ >= 2)
178 switch (id_to_index_.size())
181 num_x_plots_ = num_y_plots_ = 1;
209 while (num_x_plots_ > max_num_x_plots_)
212 num_y_plots_ =
static_cast<size_t>(ceil(id_to_index_.size() / num_x_plots_));
215 TLOG(TLVL_DEBUG) <<
"id count: " << id_to_index_.size() <<
", num_x_plots_: " << num_x_plots_ <<
" / " << max_num_x_plots_ <<
", num_y_plots_: " << num_y_plots_ <<
" / " << max_num_y_plots_;
218 void demo::WFViewer::bookCanvas_()
224 histogram_canvas_ =
new TCanvas(
"wf0");
225 histogram_canvas_->Divide(num_x_plots_, num_y_plots_);
226 histogram_canvas_->Update();
227 dynamic_cast<TRootCanvas*
>(histogram_canvas_->GetCanvasImp())->DontCallClose();
228 histogram_canvas_->SetTitle(
"ADC Value Distribution");
230 if (!digital_sum_only_)
232 graph_canvas_ =
new TCanvas(
"wf1");
233 graph_canvas_->Divide(num_x_plots_, num_y_plots_);
234 graph_canvas_->Update();
235 dynamic_cast<TRootCanvas*
>(graph_canvas_->GetCanvasImp())->DontCallClose();
236 graph_canvas_->SetTitle(
"ADC Values, Event Snapshot");
241 histogram_canvas_->Write();
242 if (graph_canvas_ !=
nullptr)
244 graph_canvas_->Write();
252 for (
auto& histogram : histograms_)
254 histogram.second =
nullptr;
257 for (
auto& graph : graphs_)
259 graph.second =
nullptr;
263 histogram_canvas_ =
nullptr;
264 graph_canvas_ =
nullptr;
270 static std::size_t evt_cntr = -1;
278 artdaq::Fragments fragments;
279 artdaq::FragmentPtrs containerFragments;
281 std::vector<art::Handle<artdaq::Fragments>> fragmentHandles;
282 #if ART_HEX_VERSION < 0x30900
283 e.getManyByType(fragmentHandles);
285 fragmentHandles = e.getMany<std::vector<artdaq::Fragment>>();
288 for (
const auto& handle : fragmentHandles)
290 if (!handle.isValid() || handle->empty())
295 if (handle->front().type() == artdaq::Fragment::ContainerFragmentType)
297 for (
const auto& cont : *handle)
299 artdaq::ContainerFragment contf(cont);
300 if (contf.fragment_type() != demo::FragmentType::TOY1 && contf.fragment_type() != demo::FragmentType::TOY2)
305 for (
size_t ii = 0; ii < contf.block_count(); ++ii)
307 containerFragments.push_back(contf[ii]);
308 fragments.push_back(*containerFragments.back());
309 if (newCanvas_ && !id_to_index_.count(fragments.back().fragmentID()))
311 auto index = id_to_index_.size();
312 id_to_index_[fragments.back().fragmentID()] = index;
319 for (
auto frag : *handle)
321 fragments.emplace_back(frag);
322 if (newCanvas_ && !id_to_index_.count(fragments.back().fragmentID()))
324 auto index = id_to_index_.size();
325 id_to_index_[fragments.back().fragmentID()] = index;
350 artdaq::Fragment::sequence_id_t expected_sequence_id = std::numeric_limits<artdaq::Fragment::sequence_id_t>::max();
353 for (
const auto& frag : fragments)
358 std::unique_ptr<ToyFragment> toyPtr;
363 if (expected_sequence_id == std::numeric_limits<artdaq::Fragment::sequence_id_t>::max())
365 expected_sequence_id = frag.sequenceID();
368 if (expected_sequence_id != frag.sequenceID())
370 TLOG(TLVL_WARNING) <<
"Warning in WFViewer: expected fragment with sequence ID " << expected_sequence_id
371 <<
", received one with sequence ID " << frag.sequenceID();
374 auto fragtype =
static_cast<FragmentType
>(frag.type());
375 std::size_t max_adc_count = std::numeric_limits<std::size_t>::max();
376 std::size_t total_adc_values = std::numeric_limits<std::size_t>::max();
380 case FragmentType::TOY1:
381 toyPtr = std::make_unique<ToyFragment>(frag);
382 total_adc_values = toyPtr->total_adc_values();
383 max_adc_count =
static_cast<size_t>(pow(2, frag.template metadata<ToyFragment::Metadata>()->num_adc_bits) - 1);
385 case FragmentType::TOY2:
386 toyPtr = std::make_unique<ToyFragment>(frag);
387 total_adc_values = toyPtr->total_adc_values();
388 max_adc_count =
static_cast<size_t>(pow(2, frag.template metadata<ToyFragment::Metadata>()->num_adc_bits) - 1);
391 throw cet::exception(
"Error in WFViewer: unknown fragment type supplied");
394 artdaq::Fragment::fragment_id_t fragment_id = frag.fragmentID();
395 if (id_to_index_.count(fragment_id) == 0u)
397 TLOG(TLVL_WARNING) <<
"Warning in WFViewer: unexpected Fragment with fragment_id " << std::to_string(fragment_id)
404 if (histograms_.count(fragment_id) == 0 || histograms_[fragment_id] ==
nullptr)
406 histograms_[fragment_id] =
407 new TH1D(Form(
"Fragment_%d_hist", fragment_id),
"", max_adc_count + 1, -0.5, max_adc_count + 0.5);
409 histograms_[fragment_id]->SetTitle(
410 Form(
"Frag %d, Type %s", fragment_id, fragmentTypeToString(fragtype).c_str()));
411 histograms_[fragment_id]->GetXaxis()->SetTitle(
"ADC value");
421 case FragmentType::TOY1:
422 case FragmentType::TOY2:
423 for (
auto val = toyPtr->dataBeginADCs(); val != toyPtr->dataEndADCs(); ++val)
425 histograms_[fragment_id]->Fill(*val);
430 TLOG(TLVL_ERROR) <<
"Error in WFViewer: unknown fragment type supplied";
431 throw cet::exception(
"Error in WFViewer: unknown fragment type supplied");
434 if (((evt_cntr % prescale_ - 1) != 0u) && prescale_ > 1)
439 std::size_t ind = id_to_index_[fragment_id];
444 if (!digital_sum_only_)
448 if (x_.size() != total_adc_values)
450 x_.resize(total_adc_values);
452 std::iota(x_.begin(), x_.end(), 0);
458 if (graphs_.count(fragment_id) == 0 || graphs_[fragment_id] ==
nullptr ||
459 static_cast<std::size_t
>(graphs_[fragment_id]->GetN()) != total_adc_values)
461 graphs_[fragment_id] =
new TGraph(total_adc_values);
462 graphs_[fragment_id]->SetName(Form(
"Fragment_%d_graph", fragment_id));
463 graphs_[fragment_id]->SetLineColor(4);
464 std::copy(x_.begin(), x_.end(), graphs_[fragment_id]->GetX());
473 case FragmentType::TOY1:
474 case FragmentType::TOY2: {
475 std::copy(toyPtr->dataBeginADCs(), toyPtr->dataBeginADCs() + total_adc_values, graphs_[fragment_id]->GetY());
480 TLOG(TLVL_ERROR) <<
"Error in WFViewer: unknown fragment type supplied";
481 throw cet::exception(
"Error in WFViewer: unknown fragment type supplied");
486 graph_canvas_->cd(ind + 1);
487 auto* pad =
static_cast<TVirtualPad*
>(graph_canvas_->GetPad(ind + 1));
489 Double_t lo_x, hi_x, lo_y, hi_y, dummy;
491 graphs_[fragment_id]->GetPoint(0, lo_x, dummy);
492 graphs_[fragment_id]->GetPoint(graphs_[fragment_id]->GetN() - 1, hi_x, dummy);
498 hi_y = max_adc_count + 0.5;
500 TH1F* padframe =
static_cast<TH1F*
>(pad->DrawFrame(lo_x, lo_y, hi_x, hi_y));
501 padframe->SetTitle(Form(
"Frag %d, Type %s, SeqID %d", static_cast<int>(fragment_id),
502 fragmentTypeToString(fragtype).c_str(),
503 static_cast<int>(expected_sequence_id)));
504 padframe->GetXaxis()->SetTitle(
"ADC #");
506 padframe->Draw(
"SAME");
511 histogram_canvas_->cd(ind + 1);
512 histograms_[fragment_id]->Draw();
514 histogram_canvas_->Modified();
515 histogram_canvas_->Update();
519 if (!digital_sum_only_)
521 graph_canvas_->cd(ind + 1);
523 graphs_[fragment_id]->Draw(
"PSAME");
525 graph_canvas_->Modified();
526 graph_canvas_->Update();
531 histogram_canvas_->Write(
"wf0", TObject::kOverwrite);
532 if (graph_canvas_ !=
nullptr)
534 graph_canvas_->Write(
"wf1", TObject::kOverwrite);
543 if (e.run() == current_run_)
547 current_run_ = e.run();
551 fFile_ =
new TFile(outputFileName_.c_str(),
"RECREATE");
555 histogram_canvas_ =
nullptr;
556 graph_canvas_ =
nullptr;
557 for (
auto& x : graphs_) x.second =
nullptr;
558 for (
auto& x : histograms_) x.second =
nullptr;
561 if (!dynamicMode_) bookCanvas_();
~WFViewer() override
WFViewer Destructor.
void analyze(art::Event const &e) override
Analyze an event. Called by art for each event in run (based on command line options) ...
void beginRun(art::Run const &) override
Art calls this function at the beginning of the run. Used for set-up of ROOT histogram objects and to...
An example art analysis module which plots events both as histograms and event snapshots (plot of ADC...
WFViewer(fhicl::ParameterSet const &p)
WFViewer Constructor.