artdaq_demo  v3_06_01
CheckIntegrity_module.cc
1 // Class: CheckIntegrity
3 // Module Type: analyzer
4 // File: CheckIntegrity_module.cc
5 // Description: Prints out information about each event.
7 
8 #include "art/Framework/Core/EDAnalyzer.h"
9 #include "art/Framework/Core/ModuleMacros.h"
10 #include "art/Framework/Principal/Event.h"
11 #include "art/Framework/Principal/Handle.h"
12 #include "canvas/Utilities/Exception.h"
13 
14 #include "artdaq-core-demo/Overlays/ToyFragment.hh"
15 #include "artdaq-core/Data/ContainerFragment.hh"
16 #include "artdaq-core/Data/Fragment.hh"
17 
18 #include "tracemf.h" // TLOG
19 #define TRACE_NAME "CheckIntegrity"
20 
21 #include <algorithm>
22 #include <cassert>
23 #include <cmath>
24 #include <fstream>
25 #include <iomanip>
26 #include <iostream>
27 #include <vector>
28 
29 namespace demo {
30 class CheckIntegrity;
31 }
32 
36 class demo::CheckIntegrity : public art::EDAnalyzer
37 {
38 public:
47  explicit CheckIntegrity( fhicl::ParameterSet const& pset );
48 
52  virtual ~CheckIntegrity() = default;
53 
58  virtual void analyze( art::Event const& evt );
59 
60 private:
61  std::string raw_data_label_;
62 };
63 
64 demo::CheckIntegrity::CheckIntegrity( fhicl::ParameterSet const& pset )
65  : EDAnalyzer( pset ), raw_data_label_( pset.get<std::string>( "raw_data_label" ) )
66 {}
67 
68 void demo::CheckIntegrity::analyze( art::Event const& evt )
69 {
70  artdaq::Fragments fragments;
71  artdaq::FragmentPtrs containerFragments;
72  std::vector<std::string> fragment_type_labels{"TOY1", "TOY2", "ContainerTOY1", "ContainerTOY2"};
73 
74  for ( auto label : fragment_type_labels )
75  {
76  art::Handle<artdaq::Fragments> fragments_with_label;
77 
78  evt.getByLabel( raw_data_label_, label, fragments_with_label );
79  if ( !fragments_with_label.isValid() ) continue;
80 
81  if ( label == "Container" || label == "ContainerTOY1" || label == "ContainerTOY2" )
82  {
83  for ( auto cont : *fragments_with_label )
84  {
85  artdaq::ContainerFragment contf( cont );
86  for ( size_t ii = 0; ii < contf.block_count(); ++ii )
87  {
88  containerFragments.push_back( contf[ ii ] );
89  fragments.push_back( *containerFragments.back() );
90  }
91  }
92  }
93  else
94  {
95  for ( auto frag : *fragments_with_label ) { fragments.emplace_back( frag ); }
96  }
97  }
98 
99  TLOG( TLVL_INFO ) << "Run " << evt.run() << ", subrun " << evt.subRun() << ", event " << evt.event() << " has "
100  << fragments.size() << " fragment(s) of type TOY1 or TOY2";
101 
102  bool err = false;
103  for ( const auto& frag : fragments )
104  {
105  ToyFragment bb( frag );
106 
107  if ( bb.hdr_event_size() * sizeof( ToyFragment::Header::data_t ) !=
108  frag.dataSize() * sizeof( artdaq::RawDataType ) )
109  {
110  TLOG( TLVL_ERROR ) << "Error: in run " << evt.run() << ", subrun " << evt.subRun() << ", event "
111  << evt.event() << ", seqID " << frag.sequenceID() << ", fragID " << frag.fragmentID()
112  << ": Size mismatch!"
113  << " ToyFragment Header reports size of "
114  << bb.hdr_event_size() * sizeof( ToyFragment::Header::data_t )
115  << " bytes, Fragment report size of " << frag.dataSize() * sizeof( artdaq::RawDataType )
116  << " bytes.";
117  continue;
118  }
119 
120  {
121  auto adc_iter = bb.dataBeginADCs();
122  ToyFragment::adc_t expected_adc = 1;
123 
124  for ( ; adc_iter != bb.dataEndADCs(); adc_iter++, expected_adc++ )
125  {
126  if ( expected_adc > bb.adc_range( frag.metadata<ToyFragment::Metadata>()->num_adc_bits ) )
127  expected_adc = 0;
128 
129  // ELF 7/10/18: Distribution type 2 is the monotonically-increasing one
130  if ( bb.hdr_distribution_type() == 2 && *adc_iter != expected_adc )
131  {
132  TLOG( TLVL_ERROR ) << "Error: in run " << evt.run() << ", subrun " << evt.subRun() << ", event "
133  << evt.event() << ", seqID " << frag.sequenceID() << ", fragID "
134  << frag.fragmentID() << ": expected an ADC value of " << expected_adc << ", got "
135  << *adc_iter;
136  err = true;
137  break;
138  }
139 
140  // ELF 7/10/18: As of now, distribution types 3 and 4 are uninitialized, and can therefore produce
141  // out-of-range counts.
142  if ( bb.hdr_distribution_type() < 3 &&
143  *adc_iter > bb.adc_range( frag.metadata<ToyFragment::Metadata>()->num_adc_bits ) )
144  {
145  TLOG( TLVL_ERROR ) << "Error: in run " << evt.run() << ", subrun " << evt.subRun() << ", event "
146  << evt.event() << ", seqID " << frag.sequenceID() << ", fragID "
147  << frag.fragmentID() << ": " << *adc_iter
148  << " is out-of-range for this Fragment type";
149  err = true;
150  break;
151  }
152  }
153  }
154  }
155  if ( !err )
156  {
157  TLOG( TLVL_DEBUG ) << "In run " << evt.run() << ", subrun " << evt.subRun() << ", event " << evt.event()
158  << ", everything is fine";
159  }
160 }
161 
162 DEFINE_ART_MODULE( demo::CheckIntegrity )
virtual void analyze(art::Event const &evt)
Analyze an event. Called by art for each event in run (based on command line options) ...
virtual ~CheckIntegrity()=default
Default destructor.
Demonstration art::EDAnalyzer which checks that all ToyFragment ADC counts are in the defined range...
CheckIntegrity(fhicl::ParameterSet const &pset)
CheckIntegrity Constructor.