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 fragmentHandles = e.getMany<std::vector<artdaq::Fragment>>();
284 for (
const auto& handle : fragmentHandles)
286 if (!handle.isValid() || handle->empty())
291 if (handle->front().type() == artdaq::Fragment::ContainerFragmentType)
293 for (
const auto& cont : *handle)
295 artdaq::ContainerFragment contf(cont);
296 if (contf.fragment_type() != demo::FragmentType::TOY1 && contf.fragment_type() != demo::FragmentType::TOY2)
301 for (
size_t ii = 0; ii < contf.block_count(); ++ii)
303 containerFragments.push_back(contf[ii]);
304 fragments.push_back(*containerFragments.back());
305 if (newCanvas_ && !id_to_index_.count(fragments.back().fragmentID()))
307 auto index = id_to_index_.size();
308 id_to_index_[fragments.back().fragmentID()] = index;
315 for (
auto frag : *handle)
317 fragments.emplace_back(frag);
318 if (newCanvas_ && !id_to_index_.count(fragments.back().fragmentID()))
320 auto index = id_to_index_.size();
321 id_to_index_[fragments.back().fragmentID()] = index;
346 artdaq::Fragment::sequence_id_t expected_sequence_id = std::numeric_limits<artdaq::Fragment::sequence_id_t>::max();
349 for (
const auto& frag : fragments)
354 std::unique_ptr<ToyFragment> toyPtr;
359 if (expected_sequence_id == std::numeric_limits<artdaq::Fragment::sequence_id_t>::max())
361 expected_sequence_id = frag.sequenceID();
364 if (expected_sequence_id != frag.sequenceID())
366 TLOG(TLVL_WARNING) <<
"Warning in WFViewer: expected fragment with sequence ID " << expected_sequence_id
367 <<
", received one with sequence ID " << frag.sequenceID();
370 auto fragtype =
static_cast<FragmentType
>(frag.type());
371 std::size_t max_adc_count = std::numeric_limits<std::size_t>::max();
372 std::size_t total_adc_values = std::numeric_limits<std::size_t>::max();
376 case FragmentType::TOY1:
377 toyPtr = std::make_unique<ToyFragment>(frag);
378 total_adc_values = toyPtr->total_adc_values();
379 max_adc_count =
static_cast<size_t>(pow(2, frag.template metadata<ToyFragment::Metadata>()->num_adc_bits) - 1);
381 case FragmentType::TOY2:
382 toyPtr = std::make_unique<ToyFragment>(frag);
383 total_adc_values = toyPtr->total_adc_values();
384 max_adc_count =
static_cast<size_t>(pow(2, frag.template metadata<ToyFragment::Metadata>()->num_adc_bits) - 1);
387 throw cet::exception(
"Error in WFViewer: unknown fragment type supplied");
390 artdaq::Fragment::fragment_id_t fragment_id = frag.fragmentID();
391 if (id_to_index_.count(fragment_id) == 0u)
393 TLOG(TLVL_WARNING) <<
"Warning in WFViewer: unexpected Fragment with fragment_id " << std::to_string(fragment_id)
400 if (histograms_.count(fragment_id) == 0 || histograms_[fragment_id] ==
nullptr)
402 histograms_[fragment_id] =
403 new TH1D(Form(
"Fragment_%d_hist", fragment_id),
"", max_adc_count + 1, -0.5, max_adc_count + 0.5);
405 histograms_[fragment_id]->SetTitle(
406 Form(
"Frag %d, Type %s", fragment_id, fragmentTypeToString(fragtype).c_str()));
407 histograms_[fragment_id]->GetXaxis()->SetTitle(
"ADC value");
417 case FragmentType::TOY1:
418 case FragmentType::TOY2:
419 for (
auto val = toyPtr->dataBeginADCs(); val != toyPtr->dataEndADCs(); ++val)
421 histograms_[fragment_id]->Fill(*val);
426 TLOG(TLVL_ERROR) <<
"Error in WFViewer: unknown fragment type supplied";
427 throw cet::exception(
"Error in WFViewer: unknown fragment type supplied");
430 if (((evt_cntr % prescale_ - 1) != 0u) && prescale_ > 1)
435 std::size_t ind = id_to_index_[fragment_id];
440 if (!digital_sum_only_)
444 if (x_.size() != total_adc_values)
446 x_.resize(total_adc_values);
448 std::iota(x_.begin(), x_.end(), 0);
454 if (graphs_.count(fragment_id) == 0 || graphs_[fragment_id] ==
nullptr ||
455 static_cast<std::size_t
>(graphs_[fragment_id]->GetN()) != total_adc_values)
457 graphs_[fragment_id] =
new TGraph(total_adc_values);
458 graphs_[fragment_id]->SetName(Form(
"Fragment_%d_graph", fragment_id));
459 graphs_[fragment_id]->SetLineColor(4);
460 std::copy(x_.begin(), x_.end(), graphs_[fragment_id]->GetX());
469 case FragmentType::TOY1:
470 case FragmentType::TOY2: {
471 std::copy(toyPtr->dataBeginADCs(), toyPtr->dataBeginADCs() + total_adc_values, graphs_[fragment_id]->GetY());
476 TLOG(TLVL_ERROR) <<
"Error in WFViewer: unknown fragment type supplied";
477 throw cet::exception(
"Error in WFViewer: unknown fragment type supplied");
482 graph_canvas_->cd(ind + 1);
483 auto* pad =
static_cast<TVirtualPad*
>(graph_canvas_->GetPad(ind + 1));
485 Double_t lo_x, hi_x, lo_y, hi_y, dummy;
487 graphs_[fragment_id]->GetPoint(0, lo_x, dummy);
488 graphs_[fragment_id]->GetPoint(graphs_[fragment_id]->GetN() - 1, hi_x, dummy);
494 hi_y = max_adc_count + 0.5;
496 TH1F* padframe =
static_cast<TH1F*
>(pad->DrawFrame(lo_x, lo_y, hi_x, hi_y));
497 padframe->SetTitle(Form(
"Frag %d, Type %s, SeqID %d", static_cast<int>(fragment_id),
498 fragmentTypeToString(fragtype).c_str(),
499 static_cast<int>(expected_sequence_id)));
500 padframe->GetXaxis()->SetTitle(
"ADC #");
502 padframe->Draw(
"SAME");
507 histogram_canvas_->cd(ind + 1);
508 histograms_[fragment_id]->Draw();
510 histogram_canvas_->Modified();
511 histogram_canvas_->Update();
515 if (!digital_sum_only_)
517 graph_canvas_->cd(ind + 1);
519 graphs_[fragment_id]->Draw(
"PSAME");
521 graph_canvas_->Modified();
522 graph_canvas_->Update();
527 histogram_canvas_->Write(
"wf0", TObject::kOverwrite);
528 if (graph_canvas_ !=
nullptr)
530 graph_canvas_->Write(
"wf1", TObject::kOverwrite);
539 if (e.run() == current_run_)
543 current_run_ = e.run();
547 fFile_ =
new TFile(outputFileName_.c_str(),
"RECREATE");
551 histogram_canvas_ =
nullptr;
552 graph_canvas_ =
nullptr;
553 for (
auto& x : graphs_) x.second =
nullptr;
554 for (
auto& x : histograms_) x.second =
nullptr;
557 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.