1 #include "art/Framework/Core/EDAnalyzer.h"
2 #include "art/Framework/Principal/Handle.h"
3 #include "art/Framework/Principal/Event.h"
4 #include "art/Framework/Principal/Run.h"
5 #include "art/Framework/Core/ModuleMacros.h"
6 #include "canvas/Utilities/InputTag.h"
8 #include "artdaq-core/Data/Fragment.hh"
9 #include "artdaq-core/Data/ContainerFragment.hh"
11 #include "artdaq-core-demo/Overlays/FragmentType.hh"
12 #include "artdaq-core-demo/Overlays/ToyFragment.hh"
14 #include "cetlib_except/exception.h"
17 #include <TRootCanvas.h>
30 #include <initializer_list>
61 explicit WFViewer(fhicl::ParameterSet
const& p);
72 void analyze(art::Event
const& e)
override;
78 void beginRun(art::Run
const&)
override;
82 std::unique_ptr<TCanvas> canvas_[2];
83 std::vector<Double_t> x_;
85 bool digital_sum_only_;
86 art::RunNumber_t current_run_;
88 std::size_t num_x_plots_;
89 std::size_t num_y_plots_;
91 std::string raw_data_label_;
92 std::vector<artdaq::Fragment::fragment_id_t> fragment_ids_;
94 std::vector<std::unique_ptr<TGraph>> graphs_;
95 std::vector<std::unique_ptr<TH1D>> histograms_;
97 std::map<artdaq::Fragment::fragment_id_t, std::size_t> id_to_index_;
98 std::string outputFileName_;
106 , prescale_(ps.get<int>(
"prescale"))
107 , digital_sum_only_(ps.get<bool>(
"digital_sum_only", false))
109 , num_x_plots_(ps.get<std::size_t>(
"num_x_plots", std::numeric_limits<std::size_t>::max()))
110 , num_y_plots_(ps.get<std::size_t>(
"num_y_plots", std::numeric_limits<std::size_t>::max()))
111 , raw_data_label_(ps.get<std::string>(
"raw_data_label",
"daq"))
112 , fragment_ids_(ps.get<std::vector<artdaq::Fragment::fragment_id_t>>(
"fragment_ids"))
113 , graphs_(fragment_ids_.size())
114 , histograms_(fragment_ids_.size())
115 , outputFileName_(ps.get<std::string>(
"fileName",
"artdaqdemo_onmon.root"))
116 , writeOutput_(ps.get<bool>(
"write_to_file", false))
118 if (num_x_plots_ == std::numeric_limits<std::size_t>::max() ||
119 num_y_plots_ == std::numeric_limits<std::size_t>::max())
121 switch (fragment_ids_.size())
123 case 1: num_x_plots_ = num_y_plots_ = 1;
125 case 2: num_x_plots_ = 2;
129 case 4: num_x_plots_ = 2;
133 case 6: num_x_plots_ = 3;
137 case 8: num_x_plots_ = 4;
141 num_x_plots_ = num_y_plots_ =
static_cast<std::size_t
>(ceil(sqrt(fragment_ids_.size())));
148 for (std::size_t i_f = 0; i_f < fragment_ids_.size(); ++i_f)
150 id_to_index_[fragment_ids_[i_f]] = i_f;
153 gStyle->SetOptStat(
"irm");
154 gStyle->SetMarkerStyle(22);
155 gStyle->SetMarkerColor(4);
160 static std::size_t evt_cntr = -1;
168 artdaq::Fragments fragments;
169 artdaq::FragmentPtrs containerFragments;
170 std::vector<std::string> fragment_type_labels{
"TOY1",
"TOY2",
"ContainerTOY1",
"ContainerTOY2"};
172 for (
auto label: fragment_type_labels)
174 art::Handle<artdaq::Fragments> fragments_with_label;
175 e.getByLabel(
"daq", label, fragments_with_label);
177 if (!fragments_with_label.isValid())
continue;
182 if (label ==
"Container" || label ==
"ContainerTOY1" || label ==
"ContainerTOY2")
184 for (
auto cont : *fragments_with_label)
186 artdaq::ContainerFragment contf(cont);
187 for (
size_t ii = 0; ii < contf.block_count(); ++ii)
189 containerFragments.push_back(contf[ii]);
190 fragments.push_back(*containerFragments.back());
196 for (
auto frag : *fragments_with_label)
198 fragments.emplace_back(frag);
217 artdaq::Fragment::sequence_id_t expected_sequence_id = std::numeric_limits<artdaq::Fragment::sequence_id_t>::max();
220 for (
const auto& frag : fragments)
225 std::unique_ptr<ToyFragment> toyPtr;
230 if (expected_sequence_id == std::numeric_limits<artdaq::Fragment::sequence_id_t>::max())
232 expected_sequence_id = frag.sequenceID();
235 if (expected_sequence_id != frag.sequenceID())
237 cerr <<
"Warning in WFViewer: expected fragment with sequence ID " << expected_sequence_id <<
", received one with sequence ID " << frag.sequenceID() << endl;
240 FragmentType fragtype =
static_cast<FragmentType
>(frag.type());
241 std::size_t max_adc_count = std::numeric_limits<std::size_t>::max();
242 std::size_t total_adc_values = std::numeric_limits<std::size_t>::max();
246 case FragmentType::TOY1:
247 toyPtr.reset(
new ToyFragment(frag));
248 total_adc_values = toyPtr->total_adc_values();
249 max_adc_count = pow(2, frag.template metadata<ToyFragment::Metadata>()->num_adc_bits) - 1;
251 case FragmentType::TOY2:
252 toyPtr.reset(
new ToyFragment(frag));
253 total_adc_values = toyPtr->total_adc_values();
254 max_adc_count = pow(2, frag.template metadata<ToyFragment::Metadata>()->num_adc_bits) - 1;
257 throw cet::exception(
"Error in WFViewer: unknown fragment type supplied");
260 artdaq::Fragment::fragment_id_t fragment_id = frag.fragmentID();
261 if (!id_to_index_.count(fragment_id))
263 cerr <<
"Warning in WFViewer: unexpected Fragment with fragment_id " << std::to_string(fragment_id) <<
" encountered!";
266 std::size_t ind = id_to_index_[fragment_id];
271 if (!histograms_[ind])
273 histograms_[ind] = std::unique_ptr<TH1D>(
new TH1D(Form(
"Fragment_%d_hist", fragment_id),
"", max_adc_count + 1, -0.5, max_adc_count + 0.5));
275 histograms_[ind]->SetTitle(Form(
"Frag %d, Type %s", fragment_id,
276 fragmentTypeToString(fragtype).c_str()));
277 histograms_[ind]->GetXaxis()->SetTitle(
"ADC value");
287 case FragmentType::TOY1:
288 case FragmentType::TOY2:
289 for (
auto val = toyPtr->dataBeginADCs(); val != toyPtr->dataEndADCs(); ++val)
290 histograms_[ind]->Fill(*val);
294 throw cet::exception(
"Error in WFViewer: unknown fragment type supplied");
297 if (evt_cntr % prescale_ - 1 && prescale_ > 1)
305 if (!digital_sum_only_)
309 if (x_.size() != total_adc_values)
311 x_.resize(total_adc_values);
313 std::iota(x_.begin(), x_.end(), 0);
319 if (!graphs_[ind] || static_cast<std::size_t>(graphs_[ind]->GetN()) != total_adc_values)
321 graphs_[ind] = std::unique_ptr<TGraph>(
new TGraph(total_adc_values));
322 graphs_[ind]->SetName(Form(
"Fragment_%d_graph", fragment_id));
323 graphs_[ind]->SetLineColor(4);
324 std::copy(x_.begin(), x_.end(), graphs_[ind]->GetX());
333 case FragmentType::TOY1:
334 case FragmentType::TOY2:
336 std::copy(toyPtr->dataBeginADCs(), toyPtr->dataBeginADCs() + total_adc_values, graphs_[ind]->GetY());
341 throw cet::exception(
"Error in WFViewer: unknown fragment type supplied");
347 canvas_[1]->cd(ind + 1);
348 TVirtualPad* pad =
static_cast<TVirtualPad*
>(canvas_[1]->GetPad(ind + 1));
350 Double_t lo_x, hi_x, lo_y, hi_y, dummy;
352 graphs_[ind]->GetPoint(0, lo_x, dummy);
353 graphs_[ind]->GetPoint(graphs_[ind]->GetN() - 1, hi_x, dummy);
359 hi_y = max_adc_count + 0.5;
362 TH1F* padframe =
static_cast<TH1F*
>(pad->DrawFrame(lo_x, lo_y, hi_x, hi_y));
363 padframe->SetTitle(Form(
"Frag %d, Type %s, SeqID %d", static_cast<int>(fragment_id),
364 fragmentTypeToString(fragtype).c_str(),
365 static_cast<int>(expected_sequence_id)));
366 padframe->GetXaxis()->SetTitle(
"ADC #");
368 padframe->Draw(
"SAME");
373 canvas_[0]->cd(ind + 1);
374 histograms_[ind]->Draw();
376 canvas_[0]->Modified();
377 canvas_[0]->Update();
381 if (!digital_sum_only_)
383 canvas_[1]->cd(ind + 1);
385 graphs_[ind]->Draw(
"PSAME");
387 canvas_[1]->Modified();
388 canvas_[1]->Update();
393 canvas_[0]->Write(
"wf0", TObject::kOverwrite);
394 canvas_[1]->Write(
"wf1", TObject::kOverwrite);
402 if (e.run() == current_run_)
return;
403 current_run_ = e.run();
407 fFile_ =
new TFile(outputFileName_.c_str(),
"RECREATE");
411 for (
int i = 0; i < 2; i++) canvas_[i] = 0;
412 for (
auto& x: graphs_) x = 0;
413 for (
auto& x: histograms_) x = 0;
415 for (
int i = 0; (i < 2 && !digital_sum_only_) || i < 1; i++)
417 canvas_[i] = std::unique_ptr<TCanvas>(
new TCanvas(Form(
"wf%d", i)));
418 canvas_[i]->Divide(num_x_plots_, num_y_plots_);
419 canvas_[i]->Update();
420 ((TRootCanvas*)canvas_[i]->GetCanvasImp())->DontCallClose();
423 canvas_[0]->SetTitle(
"ADC Value Distribution");
425 if (! digital_sum_only_)
427 canvas_[1]->SetTitle(
"ADC Values, Event Snapshot");
virtual ~WFViewer()=default
WFViewer default 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.