1 #include "art/Framework/Core/EDAnalyzer.h"
2 #include "art/Framework/Core/ModuleMacros.h"
3 #include "art/Framework/Principal/Event.h"
4 #include "art/Framework/Principal/Handle.h"
5 #include "art/Framework/Principal/Run.h"
6 #include "canvas/Utilities/InputTag.h"
8 #include "artdaq-core/Data/ContainerFragment.hh"
9 #include "artdaq-core/Data/Fragment.hh"
11 #include "artdaq-core-demo/Overlays/FragmentType.hh"
12 #include "artdaq-core-demo/Overlays/ToyFragment.hh"
14 #include "cetlib_except/exception.h"
21 #include <TRootCanvas.h>
26 #include <initializer_list>
60 explicit WFViewer( fhicl::ParameterSet
const& p );
71 void analyze( art::Event
const& e )
override;
77 void beginRun( art::Run
const& )
override;
80 TCanvas* canvas_[ 2 ];
81 std::vector<Double_t> x_;
83 bool digital_sum_only_;
84 art::RunNumber_t current_run_;
86 std::size_t num_x_plots_;
87 std::size_t num_y_plots_;
89 std::string raw_data_label_;
90 std::vector<artdaq::Fragment::fragment_id_t> fragment_ids_;
92 std::vector<TGraph*> graphs_;
93 std::vector<TH1D*> histograms_;
95 std::map<artdaq::Fragment::fragment_id_t, std::size_t> id_to_index_;
96 std::string outputFileName_;
103 : art::EDAnalyzer( ps )
104 , prescale_( ps.get<int>(
"prescale" ) )
105 , digital_sum_only_( ps.get<bool>(
"digital_sum_only", false ) )
107 , num_x_plots_( ps.get<std::size_t>(
"num_x_plots", std::numeric_limits<std::size_t>::max() ) )
108 , num_y_plots_( ps.get<std::size_t>(
"num_y_plots", std::numeric_limits<std::size_t>::max() ) )
109 , raw_data_label_( ps.get<std::string>(
"raw_data_label",
"daq" ) )
110 , fragment_ids_( ps.get<std::vector<artdaq::Fragment::fragment_id_t>>(
"fragment_ids" ) )
111 , graphs_( fragment_ids_.size() )
112 , histograms_( fragment_ids_.size() )
113 , outputFileName_( ps.get<std::string>(
"fileName",
"artdaqdemo_onmon.root" ) )
114 , writeOutput_( ps.get<bool>(
"write_to_file", false ) )
116 if ( num_x_plots_ == std::numeric_limits<std::size_t>::max() ||
117 num_y_plots_ == std::numeric_limits<std::size_t>::max() )
119 switch ( fragment_ids_.size() )
122 num_x_plots_ = num_y_plots_ = 1;
144 num_x_plots_ = num_y_plots_ =
static_cast<std::size_t
>( ceil( sqrt( fragment_ids_.size() ) ) );
151 for ( std::size_t i_f = 0; i_f < fragment_ids_.size(); ++i_f ) { id_to_index_[ fragment_ids_[ i_f ] ] = i_f; }
153 gStyle->SetOptStat(
"irm" );
154 gStyle->SetMarkerStyle( 22 );
155 gStyle->SetMarkerColor( 4 );
161 for (
size_t ind = 0; ind < histograms_.size(); ++ind ) { histograms_[ ind ] = 0; }
162 for (
size_t ind = 0; ind < graphs_.size(); ++ind ) { graphs_[ ind ] = 0; }
171 static std::size_t evt_cntr = -1;
179 artdaq::Fragments fragments;
180 artdaq::FragmentPtrs containerFragments;
181 std::vector<std::string> fragment_type_labels{
"TOY1",
"TOY2",
"ContainerTOY1",
"ContainerTOY2"};
183 for (
auto label : fragment_type_labels )
185 art::Handle<artdaq::Fragments> fragments_with_label;
186 e.getByLabel(
"daq", label, fragments_with_label );
188 if ( !fragments_with_label.isValid() )
continue;
193 if ( label ==
"Container" || label ==
"ContainerTOY1" || label ==
"ContainerTOY2" )
195 for (
auto cont : *fragments_with_label )
197 artdaq::ContainerFragment contf( cont );
198 for (
size_t ii = 0; ii < contf.block_count(); ++ii )
200 containerFragments.push_back( contf[ ii ] );
201 fragments.push_back( *containerFragments.back() );
207 for (
auto frag : *fragments_with_label ) { fragments.emplace_back( frag ); }
225 artdaq::Fragment::sequence_id_t expected_sequence_id = std::numeric_limits<artdaq::Fragment::sequence_id_t>::max();
228 for (
const auto& frag : fragments )
233 std::unique_ptr<ToyFragment> toyPtr;
238 if ( expected_sequence_id == std::numeric_limits<artdaq::Fragment::sequence_id_t>::max() )
239 { expected_sequence_id = frag.sequenceID(); }
241 if ( expected_sequence_id != frag.sequenceID() )
243 cerr <<
"Warning in WFViewer: expected fragment with sequence ID " << expected_sequence_id
244 <<
", received one with sequence ID " << frag.sequenceID() << endl;
247 FragmentType fragtype =
static_cast<FragmentType
>( frag.type() );
248 std::size_t max_adc_count = std::numeric_limits<std::size_t>::max();
249 std::size_t total_adc_values = std::numeric_limits<std::size_t>::max();
253 case FragmentType::TOY1:
254 toyPtr.reset(
new ToyFragment( frag ) );
255 total_adc_values = toyPtr->total_adc_values();
256 max_adc_count = pow( 2, frag.template metadata<ToyFragment::Metadata>()->num_adc_bits ) - 1;
258 case FragmentType::TOY2:
259 toyPtr.reset(
new ToyFragment( frag ) );
260 total_adc_values = toyPtr->total_adc_values();
261 max_adc_count = pow( 2, frag.template metadata<ToyFragment::Metadata>()->num_adc_bits ) - 1;
264 throw cet::exception(
"Error in WFViewer: unknown fragment type supplied" );
267 artdaq::Fragment::fragment_id_t fragment_id = frag.fragmentID();
268 if ( !id_to_index_.count( fragment_id ) )
270 cerr <<
"Warning in WFViewer: unexpected Fragment with fragment_id " << std::to_string( fragment_id )
274 std::size_t ind = id_to_index_[ fragment_id ];
278 if ( !histograms_[ ind ] )
281 new TH1D( Form(
"Fragment_%d_hist", fragment_id ),
"", max_adc_count + 1, -0.5, max_adc_count + 0.5 );
283 histograms_[ ind ]->SetTitle(
284 Form(
"Frag %d, Type %s", fragment_id, fragmentTypeToString( fragtype ).c_str() ) );
285 histograms_[ ind ]->GetXaxis()->SetTitle(
"ADC value" );
295 case FragmentType::TOY1:
296 case FragmentType::TOY2:
297 for (
auto val = toyPtr->dataBeginADCs(); val != toyPtr->dataEndADCs(); ++val )
298 histograms_[ ind ]->Fill( *val );
302 throw cet::exception(
"Error in WFViewer: unknown fragment type supplied" );
305 if ( evt_cntr % prescale_ - 1 && prescale_ > 1 ) {
continue; }
310 if ( !digital_sum_only_ )
314 if ( x_.size() != total_adc_values )
316 x_.resize( total_adc_values );
318 std::iota( x_.begin(), x_.end(), 0 );
324 if ( !graphs_[ ind ] || static_cast<std::size_t>( graphs_[ ind ]->GetN() ) != total_adc_values )
326 graphs_[ ind ] =
new TGraph( total_adc_values );
327 graphs_[ ind ]->SetName( Form(
"Fragment_%d_graph", fragment_id ) );
328 graphs_[ ind ]->SetLineColor( 4 );
329 std::copy( x_.begin(), x_.end(), graphs_[ ind ]->GetX() );
338 case FragmentType::TOY1:
339 case FragmentType::TOY2:
341 std::copy( toyPtr->dataBeginADCs(), toyPtr->dataBeginADCs() + total_adc_values,
342 graphs_[ ind ]->GetY() );
347 throw cet::exception(
"Error in WFViewer: unknown fragment type supplied" );
352 canvas_[ 1 ]->cd( ind + 1 );
353 TVirtualPad* pad =
static_cast<TVirtualPad*
>( canvas_[ 1 ]->GetPad( ind + 1 ) );
355 Double_t lo_x, hi_x, lo_y, hi_y, dummy;
357 graphs_[ ind ]->GetPoint( 0, lo_x, dummy );
358 graphs_[ ind ]->GetPoint( graphs_[ ind ]->GetN() - 1, hi_x, dummy );
364 hi_y = max_adc_count + 0.5;
366 TH1F* padframe =
static_cast<TH1F*
>( pad->DrawFrame( lo_x, lo_y, hi_x, hi_y ) );
367 padframe->SetTitle( Form(
"Frag %d, Type %s, SeqID %d", static_cast<int>( fragment_id ),
368 fragmentTypeToString( fragtype ).c_str(),
369 static_cast<int>( expected_sequence_id ) ) );
370 padframe->GetXaxis()->SetTitle(
"ADC #" );
372 padframe->Draw(
"SAME" );
377 canvas_[ 0 ]->cd( ind + 1 );
378 histograms_[ ind ]->Draw();
380 canvas_[ 0 ]->Modified();
381 canvas_[ 0 ]->Update();
385 if ( !digital_sum_only_ )
387 canvas_[ 1 ]->cd( ind + 1 );
389 graphs_[ ind ]->Draw(
"PSAME" );
391 canvas_[ 1 ]->Modified();
392 canvas_[ 1 ]->Update();
397 canvas_[ 0 ]->Write(
"wf0", TObject::kOverwrite );
398 canvas_[ 1 ]->Write(
"wf1", TObject::kOverwrite );
406 if ( e.run() == current_run_ )
return;
407 current_run_ = e.run();
411 fFile_ =
new TFile( outputFileName_.c_str(),
"RECREATE" );
415 for (
int i = 0; i < 2; i++ ) canvas_[ i ] = 0;
416 for (
auto& x : graphs_ ) x = 0;
417 for (
auto& x : histograms_ ) x = 0;
419 for (
int i = 0; ( i < 2 && !digital_sum_only_ ) || i < 1; i++ )
421 canvas_[ i ] =
new TCanvas( Form(
"wf%d", i ) );
422 canvas_[ i ]->Divide( num_x_plots_, num_y_plots_ );
423 canvas_[ i ]->Update();
424 ( (TRootCanvas*)canvas_[ i ]->GetCanvasImp() )->DontCallClose();
427 canvas_[ 0 ]->SetTitle(
"ADC Value Distribution" );
429 if ( !digital_sum_only_ ) { canvas_[ 1 ]->SetTitle(
"ADC Values, Event Snapshot" ); }
433 canvas_[ 0 ]->Write();
434 canvas_[ 1 ]->Write();
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...
virtual ~WFViewer()
WFViewer Destructor.
An example art analysis module which plots events both as histograms and event snapshots (plot of ADC...
WFViewer(fhicl::ParameterSet const &p)
WFViewer Constructor.