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>
59 explicit WFViewer(fhicl::ParameterSet
const& p);
70 void analyze(art::Event
const& e)
override;
76 void beginRun(art::Run
const& )
override;
84 TCanvas* histogram_canvas_;
85 TCanvas* graph_canvas_;
86 std::vector<Double_t> x_;
88 bool digital_sum_only_;
89 art::RunNumber_t current_run_;
91 std::size_t num_x_plots_;
92 std::size_t num_y_plots_;
94 std::string raw_data_label_;
95 std::vector<artdaq::Fragment::fragment_id_t> fragment_ids_;
97 std::vector<TGraph*> graphs_;
98 std::vector<TH1D*> histograms_;
100 std::map<artdaq::Fragment::fragment_id_t, std::size_t> id_to_index_;
101 std::string outputFileName_;
108 : art::EDAnalyzer(ps)
109 , prescale_(ps.get<int>(
"prescale"))
110 , digital_sum_only_(ps.get<bool>(
"digital_sum_only", false))
112 , num_x_plots_(ps.get<std::size_t>(
"num_x_plots", std::numeric_limits<std::size_t>::max()))
113 , num_y_plots_(ps.get<std::size_t>(
"num_y_plots", std::numeric_limits<std::size_t>::max()))
114 , raw_data_label_(ps.get<std::string>(
"raw_data_label",
"daq"))
115 , fragment_ids_(ps.get<std::vector<artdaq::Fragment::fragment_id_t>>(
"fragment_ids"))
116 , graphs_(fragment_ids_.size())
117 , histograms_(fragment_ids_.size())
118 , outputFileName_(ps.get<std::string>(
"fileName",
"artdaqdemo_onmon.root"))
119 , writeOutput_(ps.get<bool>(
"write_to_file", false))
121 if (num_x_plots_ == std::numeric_limits<std::size_t>::max() ||
122 num_y_plots_ == std::numeric_limits<std::size_t>::max())
124 switch (fragment_ids_.size())
127 num_x_plots_ = num_y_plots_ = 1;
149 num_x_plots_ = num_y_plots_ =
static_cast<std::size_t
>(ceil(sqrt(fragment_ids_.size())));
156 for (std::size_t i_f = 0; i_f < fragment_ids_.size(); ++i_f)
158 id_to_index_[fragment_ids_[i_f]] = i_f;
161 gStyle->SetOptStat(
"irm");
162 gStyle->SetMarkerStyle(22);
163 gStyle->SetMarkerColor(4);
169 for (
auto& histogram : histograms_)
173 for (
auto& graph : graphs_)
178 histogram_canvas_ =
nullptr;
179 graph_canvas_ =
nullptr;
185 static std::size_t evt_cntr = -1;
193 artdaq::Fragments fragments;
194 artdaq::FragmentPtrs containerFragments;
196 std::vector<art::Handle<artdaq::Fragments>> fragmentHandles;
197 #if ART_HEX_VERSION < 0x30900
198 e.getManyByType(fragmentHandles);
200 fragmentHandles = e.getMany<std::vector<artdaq::Fragment>>();
203 for (
const auto& handle : fragmentHandles)
205 if (!handle.isValid() || handle->empty())
210 if (handle->front().type() == artdaq::Fragment::ContainerFragmentType)
212 for (
const auto& cont : *handle)
214 artdaq::ContainerFragment contf(cont);
215 if (contf.fragment_type() != demo::FragmentType::TOY1 && contf.fragment_type() != demo::FragmentType::TOY2)
220 for (
size_t ii = 0; ii < contf.block_count(); ++ii)
222 containerFragments.push_back(contf[ii]);
223 fragments.push_back(*containerFragments.back());
229 if (handle->front().type() == demo::FragmentType::TOY1 || handle->front().type() == demo::FragmentType::TOY2)
231 for (
auto frag : *handle)
233 fragments.emplace_back(frag);
253 artdaq::Fragment::sequence_id_t expected_sequence_id = std::numeric_limits<artdaq::Fragment::sequence_id_t>::max();
256 for (
const auto& frag : fragments)
261 std::unique_ptr<ToyFragment> toyPtr;
266 if (expected_sequence_id == std::numeric_limits<artdaq::Fragment::sequence_id_t>::max())
268 expected_sequence_id = frag.sequenceID();
271 if (expected_sequence_id != frag.sequenceID())
273 TLOG(TLVL_WARNING) <<
"Warning in WFViewer: expected fragment with sequence ID " << expected_sequence_id
274 <<
", received one with sequence ID " << frag.sequenceID();
277 auto fragtype =
static_cast<FragmentType
>(frag.type());
278 std::size_t max_adc_count = std::numeric_limits<std::size_t>::max();
279 std::size_t total_adc_values = std::numeric_limits<std::size_t>::max();
283 case FragmentType::TOY1:
284 toyPtr = std::make_unique<ToyFragment>(frag);
285 total_adc_values = toyPtr->total_adc_values();
286 max_adc_count =
static_cast<size_t>(pow(2, frag.template metadata<ToyFragment::Metadata>()->num_adc_bits) - 1);
288 case FragmentType::TOY2:
289 toyPtr = std::make_unique<ToyFragment>(frag);
290 total_adc_values = toyPtr->total_adc_values();
291 max_adc_count =
static_cast<size_t>(pow(2, frag.template metadata<ToyFragment::Metadata>()->num_adc_bits) - 1);
294 throw cet::exception(
"Error in WFViewer: unknown fragment type supplied");
297 artdaq::Fragment::fragment_id_t fragment_id = frag.fragmentID();
298 if (id_to_index_.count(fragment_id) == 0u)
300 TLOG(TLVL_WARNING) <<
"Warning in WFViewer: unexpected Fragment with fragment_id " << std::to_string(fragment_id)
304 std::size_t ind = id_to_index_[fragment_id];
308 if (histograms_[ind] ==
nullptr)
311 new TH1D(Form(
"Fragment_%d_hist", fragment_id),
"", max_adc_count + 1, -0.5, max_adc_count + 0.5);
313 histograms_[ind]->SetTitle(
314 Form(
"Frag %d, Type %s", fragment_id, fragmentTypeToString(fragtype).c_str()));
315 histograms_[ind]->GetXaxis()->SetTitle(
"ADC value");
325 case FragmentType::TOY1:
326 case FragmentType::TOY2:
327 for (
auto val = toyPtr->dataBeginADCs(); val != toyPtr->dataEndADCs(); ++val)
329 histograms_[ind]->Fill(*val);
334 TLOG(TLVL_ERROR) <<
"Error in WFViewer: unknown fragment type supplied";
335 throw cet::exception(
"Error in WFViewer: unknown fragment type supplied");
338 if (((evt_cntr % prescale_ - 1) != 0u) && prescale_ > 1)
346 if (!digital_sum_only_)
350 if (x_.size() != total_adc_values)
352 x_.resize(total_adc_values);
354 std::iota(x_.begin(), x_.end(), 0);
360 if ((graphs_[ind] ==
nullptr) ||
static_cast<std::size_t
>(graphs_[ind]->GetN()) != total_adc_values)
362 graphs_[ind] =
new TGraph(total_adc_values);
363 graphs_[ind]->SetName(Form(
"Fragment_%d_graph", fragment_id));
364 graphs_[ind]->SetLineColor(4);
365 std::copy(x_.begin(), x_.end(), graphs_[ind]->GetX());
374 case FragmentType::TOY1:
375 case FragmentType::TOY2:
377 std::copy(toyPtr->dataBeginADCs(), toyPtr->dataBeginADCs() + total_adc_values, graphs_[ind]->GetY());
382 TLOG(TLVL_ERROR) <<
"Error in WFViewer: unknown fragment type supplied";
383 throw cet::exception(
"Error in WFViewer: unknown fragment type supplied");
388 graph_canvas_->cd(ind + 1);
389 auto* pad =
static_cast<TVirtualPad*
>(graph_canvas_->GetPad(ind + 1));
391 Double_t lo_x, hi_x, lo_y, hi_y, dummy;
393 graphs_[ind]->GetPoint(0, lo_x, dummy);
394 graphs_[ind]->GetPoint(graphs_[ind]->GetN() - 1, hi_x, dummy);
400 hi_y = max_adc_count + 0.5;
402 TH1F* padframe =
static_cast<TH1F*
>(pad->DrawFrame(lo_x, lo_y, hi_x, hi_y));
403 padframe->SetTitle(Form(
"Frag %d, Type %s, SeqID %d", static_cast<int>(fragment_id),
404 fragmentTypeToString(fragtype).c_str(),
405 static_cast<int>(expected_sequence_id)));
406 padframe->GetXaxis()->SetTitle(
"ADC #");
408 padframe->Draw(
"SAME");
413 histogram_canvas_->cd(ind + 1);
414 histograms_[ind]->Draw();
416 histogram_canvas_->Modified();
417 histogram_canvas_->Update();
421 if (!digital_sum_only_)
423 graph_canvas_->cd(ind + 1);
425 graphs_[ind]->Draw(
"PSAME");
427 graph_canvas_->Modified();
428 graph_canvas_->Update();
433 histogram_canvas_->Write(
"wf0", TObject::kOverwrite);
434 if (graph_canvas_ !=
nullptr)
436 graph_canvas_->Write(
"wf1", TObject::kOverwrite);
445 if (e.run() == current_run_)
449 current_run_ = e.run();
453 fFile_ =
new TFile(outputFileName_.c_str(),
"RECREATE");
457 for (
auto& x : graphs_)
461 for (
auto& x : histograms_)
467 histogram_canvas_ =
new TCanvas(
"wf0");
468 histogram_canvas_->Divide(num_x_plots_, num_y_plots_);
469 histogram_canvas_->Update();
470 dynamic_cast<TRootCanvas*
>(histogram_canvas_->GetCanvasImp())->DontCallClose();
471 histogram_canvas_->SetTitle(
"ADC Value Distribution");
473 if (!digital_sum_only_)
475 graph_canvas_ =
new TCanvas(
"wf1");
476 graph_canvas_->Divide(num_x_plots_, num_y_plots_);
477 graph_canvas_->Update();
478 dynamic_cast<TRootCanvas*
>(graph_canvas_->GetCanvasImp())->DontCallClose();
479 graph_canvas_->SetTitle(
"ADC Values, Event Snapshot");
484 histogram_canvas_->Write();
485 if (graph_canvas_ !=
nullptr)
487 graph_canvas_->Write();
~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.