LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
OpDigiAna_module.cc
Go to the documentation of this file.
1 // Christie Chiu and Ben Jones, MIT, 2012
2 //
3 // This is an analyzer module which writes the raw optical
4 // detector pulses for each PMT to an output file
5 //
6 
7 // LArSoft includes
10 
11 // Framework includes
17 #include "art_root_io/TFileService.h"
19 #include "fhiclcpp/ParameterSet.h"
20 
21 // ROOT includes
22 #include "TH1.h"
23 
24 // C++ Includes
25 #include <algorithm>
26 
27 namespace opdet {
28 
29  class OpDigiAna : public art::EDAnalyzer {
30  public:
31  // Standard constructor and destructor for an ART module.
33 
34  // The analyzer routine, called once per event.
35  void analyze(const art::Event&);
36 
37  private:
38  // The stuff below is the part you'll most likely have to change to
39  // go from this custom example to your own task.
40 
41  // The parameters we'll read from the .fcl file.
42  std::string fInputModule; // Input tag for OpDet collection
43  std::string fInstanceName; // Input tag for OpDet collection
44  float fSampleFreq; // in MHz
45  float fTimeBegin; // in us
46  float fTimeEnd; // in us
47  // short fPEheight; // in ADC counts
49 
50  double fSPEAmp;
51 
54  };
55 
56 }
57 
58 namespace opdet {
59 
60  //-----------------------------------------------------------------------
61  // Constructor
63  {
64 
66  fSPEAmp = odp->GetSPECumulativeAmplitude();
67  fTimeBegin = odp->TimeBegin();
68  fTimeEnd = odp->TimeEnd();
69  fSampleFreq = odp->SampleFreq();
70 
71  // Indicate that the Input Module comes from .fcl
72  fInputModule = pset.get<std::string>("InputModule");
73  fInstanceName = pset.get<std::string>("InstanceName");
74  fZeroSupThresh = pset.get<double>("ZeroSupThresh") * fSPEAmp;
75 
76  fMakeBipolarHist = pset.get<bool>("MakeBipolarHist");
77  fMakeUnipolarHist = pset.get<bool>("MakeUnipolarHist");
78  }
79 
80  //-----------------------------------------------------------------------
82  {
83 
84  // Create a handle for our vector of pulses
86 
87  // Create string for histogram name
88  char HistName[50];
89 
90  // Read in WaveformHandle
91  evt.getByLabel(fInputModule, fInstanceName, WaveformHandle);
92 
93  // Access ART's TFileService, which will handle creating and writing
94  // histograms for us.
96 
97  std::vector<std::string> histnames;
98 
99  // For every OpDet waveform in the vector given by WaveformHandle
100  for (unsigned int i = 0; i < WaveformHandle->size(); ++i) {
101  // Get OpDetPulse
102  art::Ptr<raw::OpDetPulse> ThePulsePtr(WaveformHandle, i);
103  raw::OpDetPulse ThePulse = *ThePulsePtr;
104 
105  // Make an instance of histogram and its pointer, changing all units to ns
106  // Notice that histogram axis is in ns but binned by 1/64MHz;
107  // appropriate conversions are made from beginning and end time
108  // in us, and frequency in MHz.
109 
110  // Make sure the histogram name is unique since there can be multiple pulses
111  // per event and photo detector
112  unsigned int pulsenum = 0;
113  while (true) {
114  sprintf(
115  HistName, "Event_%d_OpDet_%i_Pulse_%i", evt.id().event(), ThePulse.OpChannel(), pulsenum);
116  auto p = std::find(histnames.begin(), histnames.end(), HistName);
117  if (p != histnames.end()) {
118  // Found a duplicate
119  pulsenum++;
120  }
121  else {
122  // Found a unique name
123  histnames.push_back(HistName);
124  break;
125  }
126  }
127 
128  TH1D* PulseHist = nullptr;
129  if (fMakeBipolarHist) {
130  PulseHist = tfs->make<TH1D>(HistName,
131  ";t (ns);",
132  int((fTimeEnd - fTimeBegin) * fSampleFreq),
133  fTimeBegin * 1000.,
134  fTimeEnd * 1000.);
135  }
136 
137  sprintf(HistName,
138  "Event_%d_uni_OpDet_%i_Pulse_%i",
139  evt.id().event(),
140  ThePulse.OpChannel(),
141  pulsenum);
142  TH1D* UnipolarHist = nullptr;
143  if (fMakeUnipolarHist) {
144  UnipolarHist = tfs->make<TH1D>(HistName,
145  ";t (ns);",
146  int((fTimeEnd - fTimeBegin) * fSampleFreq),
147  fTimeBegin * 1000.,
148  fTimeEnd * 1000.);
149  }
150 
151  for (unsigned int binNum = 0; binNum < ThePulse.Waveform().size(); ++binNum) {
152  // Fill histogram with waveform
153 
154  if (fMakeBipolarHist) PulseHist->SetBinContent(binNum, (double)ThePulse.Waveform()[binNum]);
155  if ((binNum > 0) && (fMakeUnipolarHist)) {
156  double BinContent =
157  (double)ThePulse.Waveform()[binNum] + (double)UnipolarHist->GetBinContent(binNum - 1);
158  if (BinContent > fZeroSupThresh)
159  UnipolarHist->SetBinContent(binNum, BinContent);
160  else
161  UnipolarHist->SetBinContent(binNum, 0);
162  }
163  }
164  }
165  }
166 
167 } // namespace opdet
168 
169 namespace opdet {
171 }
std::string fInputModule
unsigned short OpChannel() const
Definition: OpDetPulse.h:62
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.cc:6
const std::vector< short > & Waveform() const
Definition: OpDetPulse.h:54
std::string fInstanceName
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
T get(std::string const &key) const
Definition: ParameterSet.h:314
OpDigiAna(const fhicl::ParameterSet &)
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
void analyze(const art::Event &)
EventNumber_t event() const
Definition: EventID.h:116
TCEvent evt
Definition: DataStructs.cxx:8
Definition: fwd.h:26
EventID id() const
Definition: Event.cc:23