AverageWaveform_module.cc
Go to the documentation of this file.
1 //==========================================================
2 // AverageWaveform_module.cc
3 // This module finds the average waveform on each channel.
4 //
5 // Alex Himmel, ahimmel@fnal.gov
6 // Based on OpDigiAna_module.cc
7 //==========================================================
8 
9 #ifndef AVERAGEWAVEFORM_H
10 #define AVERAGEWAVEFORM_H 1
11 
12 // Framework includes
13 
19 #include "art_root_io/TFileService.h"
20 #include "art_root_io/TFileDirectory.h"
22 #include "fhiclcpp/ParameterSet.h"
24 
25 // LArSoft includes
26 
30 
31 // ROOT includes
32 
33 #include "TH1.h"
34 
35 // C++ includes
36 
37 #include <vector>
38 #include <map>
39 #include <cstring>
40 
41 namespace opdet {
42 
44 
45  public:
46 
47  // Standard constructor and destructor for an ART module
49  virtual ~AverageWaveform();
50 
51  // The analyzer routine, called once per event
52  void analyze(art::Event const&) override;
53 
54  private:
55  void beginJob() override;
56  void endJob () override;
57 
58  // Parameters we'll read from the fcl-file
59  std::string fInputModule; // Module used to create OpDetWaveforms
60  std::string fInstanceName;// Input tag for OpDetWaveforms collection
61  double fSampleFreq; // Sampling frequency in MHz
62  double fTimeBegin; // Beginning of sample in us
63  int fBaselineSubtract; // Baseline to subtract from each waveform
64  int fNticks;
65 
66  // Map to store how many waveforms are on one optical channel
67  std::map< int, TH1D* > averageWaveforms;
68  std::map< int, int > waveformCount;
71 
72 
73  };
74 
75 }
76 
77 #endif
78 
79 namespace opdet {
80 
82 
83 }
84 
85 namespace opdet {
86 
87  //---------------------------------------------------------------------------
88  // Constructor
90  : EDAnalyzer(pset)
91  , fInputModule { pset.get< std::string >("InputModule") }
92  , fInstanceName { pset.get< std::string >("InstanceName") }
93  , fTimeBegin { 0 }
94  , fBaselineSubtract { pset.get< int >("BaselineSubtract", 0) }
95  , fNticks { pset.get< int >("Nticks", 0) }
96  , averageWaveformAll{ NULL }
97  , eventCount { 0 }
98  {
99 
100  // Obtain parameters from TimeService
101  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataForJob();
102  fSampleFreq = clockData.OpticalClock().Frequency();
103 
104  // Assume starting at 0
105  fTimeBegin = 0;
106 
107  }
108 
109  //---------------------------------------------------------------------------
110  // Destructor
112  {
113  }
114 
115 
116  //---------------------------------------------------------------------------
118  {
119  }
120 
121  //---------------------------------------------------------------------------
123  {
124  double waveformCountAll = 0;
125  for (auto iter = averageWaveforms.begin(); iter != averageWaveforms.end(); iter++)
126  {
127  waveformCountAll += waveformCount[iter->first];
128  mf::LogInfo("AverageWaveform") << "Scaling down channel " << iter->first << " by 1./" << waveformCount[iter->first] << std::endl;
129  iter->second->Scale(1./waveformCount[iter->first]);
130  }
131  mf::LogInfo("AverageWaveform") << "Scaling down all channels by 1./" << eventCount << std::endl;
132  averageWaveformAll->Scale(1./eventCount);
133  }
134 
135 
136  //---------------------------------------------------------------------------
138  {
139 
140  // Get OpDetWaveforms from the event
142  auto waveformHandle = evt.getHandle< std::vector< raw::OpDetWaveform > >(itag1);
143 
144  // Access ART's TFileService, which will handle creating and writing
145  // histograms for us
147 
148  for (size_t i = 0; i < waveformHandle->size(); i++)
149  {
150 
151 
152  // This was probably required to overcome the "const" problem
153  // with OpDetPulse::Waveform()
154  art::Ptr< raw::OpDetWaveform > waveformPtr(waveformHandle, i);
155  raw::OpDetWaveform pulse = *waveformPtr;
156  int channel = pulse.ChannelNumber();
157 
158  if (fNticks == 0) fNticks = pulse.size();
159 
160 
161  // Create the TH1 if it doesn't exist
162  auto waveform = averageWaveforms.find( channel );
163  if ( waveform == averageWaveforms.end() ) {
164  TString histName = TString::Format("avgwaveform_channel_%03i", channel);
165  averageWaveforms[channel] = tfs->make< TH1D >(histName, ";t (us);", fNticks, 0, float(fNticks+1) / fSampleFreq);
166  }
167  if (!averageWaveformAll) {
168  averageWaveformAll = tfs->make< TH1D >("avgwaveform_channel_all", ";t (us);", fNticks, 0, float(fNticks+1) / fSampleFreq);
169  }
170 
171  // Add this waveform to this histogram
172  for (size_t tick = 0; tick < pulse.size(); tick++) {
174  averageWaveformAll->Fill(double(tick)/fSampleFreq, pulse[tick] - fBaselineSubtract);
175  }
176 
177  // Count number of waveforms on each channel
179  }
180  eventCount++;
181 
182  }
183 
184 }
Format
Definition: utils.h:7
void analyze(art::Event const &) override
Channel_t ChannelNumber() const
Definition: OpDetWaveform.h:65
Handle< PROD > getHandle(SelectorBase const &) const
Definition: DataViewImpl.h:382
std::string string
Definition: nybbler.cc:12
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
std::map< int, int > waveformCount
std::map< int, TH1D * > averageWaveforms
AverageWaveform(fhicl::ParameterSet const &)
uint8_t channel
Definition: CRTFragment.hh:201
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:25
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
T get(std::string const &key) const
Definition: ParameterSet.h:271
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
Definition: electronics.h:75
TCEvent evt
Definition: DataStructs.cxx:7
Definition: fwd.h:31
QTextStream & endl(QTextStream &s)