LEDCalibrationAna_module.cc
Go to the documentation of this file.
1 // -*- mode: c++; c-basic-offset: 2; -*-
2 // Ben Jones, MIT, 2013
3 //
4 // This ana module extracts pedestals and gains from
5 // LED calibration run data (incomplete)
6 //
7 
8 // LArSoft includes
18 
19 // Framework includes
25 #include "art_root_io/TFileService.h"
26 #include "fhiclcpp/ParameterSet.h"
27 
28 // ROOT includes
29 #include "TF1.h"
30 #include "TH1.h"
31 #include <TTree.h>
32 
33 // C++ Includes
34 #include "math.h"
35 #include <cstring>
36 #include <iostream>
37 #include <map>
38 #include <sstream>
39 
40 namespace opdet {
41 
43  public:
44  // Standard constructor and destructor for an ART module.
46 
47  void endJob();
48 
49  // The analyzer routine, called once per event.
50  void analyze(const art::Event&);
51 
52  private:
53  // The parameters we'll read from the .fcl file.
54  std::string fInputModule; // Input tag for OpDet collection
55  uint32_t fTriggerChannel;
57  float fMaxTimeMean;
59  float fAreaDivs;
60  float fAreaMin;
61  float fAreaMax;
63 
67  TTree* fPulseTree;
69  Float_t fPeak;
70  Float_t fPedRMS;
71  Float_t fPedMean;
72  Float_t fArea;
73  Float_t fTBegin;
74  Float_t fTEnd;
75  Float_t fTMax;
76  Float_t fOffset;
77  Int_t fEventID;
78  Int_t fRunID;
79  Int_t fChannel;
80  Int_t fShaper;
81 
82  uint32_t ShaperToChannel(uint32_t Shaper);
83 
85 
86  std::map<uint32_t, std::vector<double>> fAreas;
87  };
88 
89 }
90 
91 namespace opdet {
92 
93  //-----------------------------------------------------------------------
94  // Constructor
97  {
98  // Indicate that the Input Module comes from .fcl
99  fInputModule = pset.get<std::string>("InputModule");
100  fTriggerChannel = pset.get<uint32_t>("TriggerChannel");
101  fTriggerDelay = pset.get<uint32_t>("TriggerDelay");
102  fCoincThreshold = pset.get<float>("CoincThreshold");
103  fMaxTimeThresh = pset.get<float>("MaxTimeThresh");
104  fMaxTimeMean = pset.get<float>("MaxTimeMean");
105  fAreaMin = pset.get<float>("AreaMin");
106  fAreaMax = pset.get<float>("AreaMax");
107  fAreaDivs = pset.get<float>("AreaDivs");
108  fMakeNonCoincTree = pset.get<bool>("MakeNonCoincTree");
109 
112 
114 
115  fPulseTree = tfs->make<TTree>("fPulseTree", "fPulseTree");
116  fPulseTree->Branch("Area", &fArea, "Area/F");
117  fPulseTree->Branch("Peak", &fPeak, "Peak/F");
118  fPulseTree->Branch("TBegin", &fTBegin, "TBegin/F");
119  fPulseTree->Branch("TEnd", &fTEnd, "TEnd/F");
120  fPulseTree->Branch("TMax", &fTMax, "TMax/F");
121  fPulseTree->Branch("Channel", &fChannel, "Channel/I");
122  fPulseTree->Branch("Shaper", &fShaper, "Shaper/I");
123  fPulseTree->Branch("PedMean", &fPedMean, "PedMean/F");
124  fPulseTree->Branch("PedRMS", &fPedRMS, "PedRMS/F");
125  fPulseTree->Branch("Offset", &fOffset, "Offset/F");
126  fPulseTree->Branch("EventID", &fEventID, "EventID/I");
127  fPulseTree->Branch("RunID", &fRunID, "RunID/I");
128 
129  fPulseTreeNonCoinc = tfs->make<TTree>("fPulseTreeNonCoinc", "fPulseTreeNonCoinc");
130  fPulseTreeNonCoinc->Branch("Area", &fArea, "Area/F");
131  fPulseTreeNonCoinc->Branch("Peak", &fPeak, "Peak/F");
132  fPulseTreeNonCoinc->Branch("TBegin", &fTBegin, "TBegin/F");
133  fPulseTreeNonCoinc->Branch("TEnd", &fTEnd, "TEnd/F");
134  fPulseTreeNonCoinc->Branch("TMax", &fTMax, "TMax/F");
135  fPulseTreeNonCoinc->Branch("Channel", &fChannel, "Channel/I");
136  fPulseTreeNonCoinc->Branch("Shaper", &fShaper, "Shaper/I");
137  fPulseTreeNonCoinc->Branch("PedMean", &fPedMean, "PedMean/F");
138  fPulseTreeNonCoinc->Branch("PedRMS", &fPedRMS, "PedRMS/F");
139  fPulseTreeNonCoinc->Branch("EventID", &fEventID, "EventID/I");
140  fPulseTreeNonCoinc->Branch("RunID", &fRunID, "RunID/I");
141  }
142 
143  //-----------------------------------------------------------------------
144  void
146  {
148 
149  for (auto it = fAreas.begin(); it != fAreas.end(); ++it) {
150  uint32_t Channel = it->first;
151 
152  std::stringstream histname;
153  histname.flush();
154  histname << "ch" << Channel << "area";
155 
156  TH1D* HistArea = tfs->make<TH1D>(
157  histname.str().c_str(), histname.str().c_str(), fAreaDivs, fAreaMin, fAreaMax);
158 
159  for (size_t j = 0; j != it->second.size(); ++j) {
160  HistArea->Fill(it->second.at(j));
161  }
162 
163  std::stringstream fitname;
164  fitname.flush();
165  fitname << "ch" << Channel << "fit";
166 
167  double Max = HistArea->GetMaximum();
168  double Mid = HistArea->GetBinContent(fAreaDivs / 2.);
169 
170  TF1* GausFit = new TF1(fitname.str().c_str(), "gaus(0)+gaus(3)+gaus(6)", fAreaMin, fAreaMax);
171 
172  GausFit->SetParameters(Mid,
173  (fAreaMin + fAreaMax) / 2.,
174  (fAreaMax - fAreaMin) / 2.,
175  Max,
176  0,
177  (fAreaMin + fAreaMax) / 8.,
178  Max / 5.,
179  0,
180  (fAreaMin + fAreaMax) / 4.);
181 
182  GausFit->SetParLimits(0, 0, 1.1 * Max);
183  GausFit->SetParLimits(1, 0, fAreaMax);
184  GausFit->SetParLimits(2, 0, fAreaMax);
185 
186  GausFit->SetParLimits(3, 0, 1.1 * Max);
187  GausFit->FixParameter(4, 0);
188  GausFit->SetParLimits(5, 0, (fAreaMin + fAreaMax) / 2.);
189 
190  GausFit->SetParLimits(6, 0, 1.1 * Max);
191  GausFit->FixParameter(7, 0);
192  GausFit->SetParLimits(8, 0, (fAreaMin + fAreaMax) / 2.);
193 
194  HistArea->Fit(GausFit);
195 
196  double Mean = GausFit->GetParameter(1);
197  double Width = GausFit->GetParameter(2);
198 
199  double MeanErr = GausFit->GetParError(1);
200  double WidthErr = GausFit->GetParError(2);
201 
202  double NPE = pow(Mean, 2) / pow(Width, 2);
203  double SPEScale = Mean / NPE;
204 
205  double NPEError = NPE * pow(2. * (pow(MeanErr / Mean, 2) + pow(WidthErr / Width, 2)), 0.5);
206  double SPEError = SPEScale * pow(2. * pow(WidthErr / Width, 2) + pow(MeanErr / Mean, 2), 0.5);
207 
208  std::cout << "Channel " << Channel << ":\tSPE Scale \t" << SPEScale << "\t +/- \t" << SPEError
209  << ",\t NPE \t" << NPE << "\t +/- \t" << NPEError << std::endl;
210  }
211  }
212 
213  //-----------------------------------------------------------------------
214  void
216  {
217  auto const clock_data =
219 
220  fRunID = evt.run();
221  fEventID = evt.event();
222 
223  // Create a handle for our vector of pulses
224  art::Handle<std::vector<raw::OpDetWaveform>> OpDetWaveformHandle;
225 
226  // Read in WaveformHandle
227  evt.getByLabel(fInputModule, OpDetWaveformHandle);
228 
229  std::map<uint32_t, std::vector<int>> OrgOpDigitByChannel;
230 
231  for (size_t i = 0; i != OpDetWaveformHandle->size(); ++i) {
232  OrgOpDigitByChannel[ShaperToChannel(OpDetWaveformHandle->at(i).ChannelNumber())].push_back(i);
233  }
234 
235  std::vector<uint32_t> FrameNumbersForTrig;
236  std::vector<uint32_t> TimeSlicesForTrig;
237 
238  for (size_t i = 0; i != OrgOpDigitByChannel[fTriggerChannel].size(); ++i) {
239  double TimeStamp =
240  OpDetWaveformHandle->at(OrgOpDigitByChannel[fTriggerChannel][i]).TimeStamp();
241  uint32_t Frame = clock_data.OpticalClock().Frame(TimeStamp);
242  uint32_t TimeSlice = clock_data.OpticalClock().Sample(TimeStamp);
243  FrameNumbersForTrig.push_back(Frame);
244  TimeSlicesForTrig.push_back(TimeSlice);
245  }
246 
247  for (size_t i = 0; i != OpDetWaveformHandle->size(); ++i) {
248  double TimeStamp = OpDetWaveformHandle->at(i).TimeStamp();
249  uint32_t Frame = clock_data.OpticalClock().Frame(TimeStamp);
250  uint32_t TimeSlice = clock_data.OpticalClock().Sample(TimeStamp);
251  fShaper = OpDetWaveformHandle->at(i).ChannelNumber();
253 
254  if (uint32_t(fChannel) != fTriggerChannel) {
255  for (size_t j = 0; j != FrameNumbersForTrig.size(); ++j) {
256  if ((Frame == FrameNumbersForTrig.at(j)) &&
257  (fabs(TimeSlice - TimeSlicesForTrig.at(j) - fTriggerDelay) < fCoincThreshold)) {
258 
259  const raw::OpDetWaveform& wf = OpDetWaveformHandle->at(i);
260 
261  //fPulseRecoMgr.RecoPulse(wf);
263 
264  size_t NPulses = fThreshAlg.GetNPulse();
265 
266  fOffset = TimeSlice - TimeSlicesForTrig.at(j);
267  //fPedMean = fThreshAlg.PedMean();
268  //fPedRMS = fThreshAlg.PedRms();
269 
270  for (size_t k = 0; k != NPulses; ++k) {
272 
280 
281  fPulseTree->Fill();
282 
283  fAreas[fChannel].push_back(fArea);
284  }
285  else if (fMakeNonCoincTree) {
291 
292  fPulseTreeNonCoinc->Fill();
293  }
294  }
295  }
296  }
297  }
298  }
299  }
300 
301  //---------------------------------
302  uint32_t
304  {
305  static std::map<uint32_t, uint32_t> ShaperToChannelMap;
306  if (ShaperToChannelMap.size() == 0) {
307 
308  // temporary
309  for (size_t i = 0; i != 40; ++i) {
310  ShaperToChannelMap[i] = i;
311  }
312  }
313 
314  return ShaperToChannelMap[Shaper];
315  }
316 
317 } // namespace opdet
318 
319 namespace opdet {
321 }
pmtana::AlgoThreshold fThreshAlg
EventNumber_t event() const
Definition: DataViewImpl.cc:85
std::string string
Definition: nybbler.cc:12
constexpr T pow(T x)
Definition: pow.h:72
double Width(Resonance_t res)
resonance width (GeV)
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:25
void AddRecoAlgo(pmtana::PMTPulseRecoBase *algo, PMTPedestalBase *ped_algo=nullptr)
A method to set pulse reconstruction algorithm.
void analyze(const art::Event &)
size_t GetNPulse() const
A getter for the number of reconstructed pulses from the input waveform.
pmtana::PulseRecoManager fPulseRecoMgr
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Definition: DataViewImpl.h:633
fInnerVessel push_back(Point(-578.400000, 0.000000, 0.000000))
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
bool Reconstruct(const pmtana::Waveform_t &) const
Implementation of ana_base::analyze method.
T get(std::string const &key) const
Definition: ParameterSet.h:271
RunNumber_t run() const
Definition: DataViewImpl.cc:71
Class definition file of AlgoThreshold.
void SetDefaultPedAlgo(pmtana::PMTPedestalBase *algo)
A method to set a choice of pedestal estimation method.
std::map< uint32_t, std::vector< double > > fAreas
Class definition file of PMTPulseRecoBase.
Class definition file of PedAlgoEdges.
TCEvent evt
Definition: DataStructs.cxx:7
uint32_t ShaperToChannel(uint32_t Shaper)
LEDCalibrationAna(const fhicl::ParameterSet &)
const pulse_param & GetPulse(size_t index=0) const
QTextStream & endl(QTextStream &s)
pure virtual base interface for detector clocks
Class definition file of PulseRecoManager.