LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
OpFlashAna_module.cc
Go to the documentation of this file.
1 // -*- mode: c++; c-basic-offset: 2; -*-
2 // This analyzer writes out a TTree containing the properties of
3 // each reconstructed flash
4 //
5 
6 // ROOT includes
7 #include "TH1.h"
8 #include "TH2.h"
9 #include "TTree.h"
10 
11 // C++ includes
12 #include "math.h"
13 #include <cstring>
14 
15 // LArSoft includes
20 
21 // ART includes.
27 #include "art_root_io/TFileService.h"
30 #include "fhiclcpp/ParameterSet.h"
31 
32 namespace opdet {
33 
34  class OpFlashAna : public art::EDAnalyzer {
35  public:
36  // Standard constructor and destructor for an ART module.
38 
39  // The analyzer routine, called once per event.
40  void analyze(const art::Event&);
41 
42  private:
43  // The stuff below is the part you'll most likely have to change to
44  // go from this custom example to your own task.
45 
46  // The parameters we'll read from the .fcl file.
47  std::string fOpFlashModuleLabel; // Input tag for OpFlash collection
48  std::string fOpHitModuleLabel; // Input tag for OpHit collection
49  float fSampleFreq; // in MHz
50  float fTimeBegin; // in us
51  float fTimeEnd; // in us
52 
53  float fYMin, fYMax, fZMin, fZMax;
54 
56 
60 
66 
68  TTree* fPerFlashTree;
69  TTree* fPerOpHitTree;
72 
73  Int_t fEventID;
74  Int_t fFlashID;
75  Int_t fHitID;
76  Double_t fFlashTime;
77  Double_t fAbsTime;
80  Float_t fTotalPE;
81  Int_t fFlashFrame;
82 
83  Float_t fNPe;
84  Float_t fYCenter;
85  Float_t fYWidth;
86  Float_t fZCenter;
87  Float_t fZWidth;
88 
89  Int_t fOpChannel;
90  Double_t fPeakTimeAbs;
91  Double_t fPeakTime;
92  Int_t fFrame;
93  Float_t fWidth;
94  Float_t fArea;
95  Float_t fAmplitude;
96  Float_t fPE;
97  Float_t fFastToTotal;
98 
99  int fNFlashes;
100  std::vector<int> fFlashIDVector;
101  std::vector<float> fYCenterVector;
102  std::vector<float> fZCenterVector;
103  std::vector<float> fYWidthVector;
104  std::vector<float> fZWidthVector;
105  std::vector<double> fFlashTimeVector;
106  std::vector<double> fAbsTimeVector;
107  std::vector<int> fFlashFrameVector;
108  std::vector<bool> fInBeamFrameVector;
109  std::vector<int> fOnBeamTimeVector;
110  std::vector<float> fTotalPEVector;
112  std::vector<float> fPEsPerFlashPerChannelVector;
113  };
114 
115 }
116 
117 namespace opdet {
118 
119  //-----------------------------------------------------------------------
120  // Constructor
122  {
123 
124  // Indicate that the Input Module comes from .fcl
125  fOpFlashModuleLabel = pset.get<std::string>("OpFlashModuleLabel");
126  fOpHitModuleLabel = pset.get<std::string>("OpHitModuleLabel");
127 
128  // art::ServiceHandle<OpDigiProperties const> odp;
129  // fTimeBegin = odp->TimeBegin();
130  // fTimeEnd = odp->TimeEnd();
131  // fSampleFreq = odp->SampleFreq();
132 
133  auto const clock_data =
135  fTimeBegin = clock_data.OpticalClock().Time();
136  fTimeEnd = clock_data.OpticalClock().FramePeriod();
137  fSampleFreq = clock_data.OpticalClock().Frequency();
138 
139  fYMin = pset.get<float>("YMin");
140  fYMax = pset.get<float>("YMax");
141  fZMin = pset.get<float>("ZMin");
142  fZMax = pset.get<float>("ZMax");
143 
144  fMakeFlashTimeHist = pset.get<bool>("MakeFlashTimeHist");
145  fMakeFlashPosHist = pset.get<bool>("MakeFlashPosHist");
146  fMakePerFlashHists = pset.get<bool>("MakePerFlashHists");
147 
148  fMakePerEventFlashTree = pset.get<bool>("MakePerEventFlashTree");
149  fMakePerFlashTree = pset.get<bool>("MakePerFlashTree");
150  fMakePerOpHitTree = pset.get<bool>("MakePerOpHitTree");
151  fMakeFlashBreakdownTree = pset.get<bool>("MakeFlashBreakdownTree");
152  fMakeFlashHitMatchTree = pset.get<bool>("MakeFlashHitMatchTree");
153 
154  PosHistYRes = 100;
155  PosHistZRes = 100;
156 
158 
159  if (fMakeFlashBreakdownTree) {
160  fFlashBreakdownTree = tfs->make<TTree>("FlashBreakdownTree", "FlashBreakdownTree");
161  fFlashBreakdownTree->Branch("EventID", &fEventID, "EventID/I");
162  fFlashBreakdownTree->Branch("FlashID", &fFlashID, "FlashID/I");
163  fFlashBreakdownTree->Branch("OpChannel", &fOpChannel, "OpChannel/I");
164  fFlashBreakdownTree->Branch("FlashTime", &fFlashTime, "FlashTime/D");
165  fFlashBreakdownTree->Branch("NPe", &fNPe, "NPe/F");
166  fFlashBreakdownTree->Branch("AbsTime", &fAbsTime, "AbsTime/D");
167  fFlashBreakdownTree->Branch("FlashFrame", &fFlashFrame, "FlashFrame/I");
168  fFlashBreakdownTree->Branch("InBeamFrame", &fInBeamFrame, "InBeamFrame/B");
169  fFlashBreakdownTree->Branch("OnBeamTime", &fOnBeamTime, "OnBeamTime/I");
170  fFlashBreakdownTree->Branch("YCenter", &fYCenter, "YCenter/F");
171  fFlashBreakdownTree->Branch("ZCenter", &fZCenter, "ZCenter/F");
172  fFlashBreakdownTree->Branch("YWidth", &fYWidth, "YWidth/F");
173  fFlashBreakdownTree->Branch("ZWidth", &fZWidth, "ZWidth/F");
174  fFlashBreakdownTree->Branch("TotalPE", &fTotalPE, "TotalPE/F");
175  }
176 
177  if (fMakePerOpHitTree) {
178  fPerOpHitTree = tfs->make<TTree>("PerOpHitTree", "PerOpHitTree");
179  fPerOpHitTree->Branch("EventID", &fEventID, "EventID/I");
180  fPerOpHitTree->Branch("HitID", &fHitID, "HitID/I");
181  fPerOpHitTree->Branch("OpChannel", &fOpChannel, "OpChannel/I");
182  fPerOpHitTree->Branch("PeakTimeAbs", &fPeakTimeAbs, "PeakTimeAbs/D");
183  fPerOpHitTree->Branch("PeakTime", &fPeakTime, "PeakTime/D");
184  fPerOpHitTree->Branch("Frame", &fFrame, "Frame/I");
185  fPerOpHitTree->Branch("Width", &fWidth, "Width/F");
186  fPerOpHitTree->Branch("Area", &fArea, "Area/F");
187  fPerOpHitTree->Branch("Amplitude", &fAmplitude, "Amplitude/F");
188  fPerOpHitTree->Branch("PE", &fPE, "PE/F");
189  fPerOpHitTree->Branch("FastToTotal", &fFastToTotal, "FastToTotal/F");
190  }
191 
192  if (fMakePerFlashTree) {
193  fPerFlashTree = tfs->make<TTree>("PerFlashTree", "PerFlashTree");
194  fPerFlashTree->Branch("EventID", &fEventID, "EventID/I");
195  fPerFlashTree->Branch("FlashID", &fFlashID, "FlashID/I");
196  fPerFlashTree->Branch("YCenter", &fYCenter, "YCenter/F");
197  fPerFlashTree->Branch("ZCenter", &fZCenter, "ZCenter/F");
198  fPerFlashTree->Branch("YWidth", &fYWidth, "YWidth/F");
199  fPerFlashTree->Branch("ZWidth", &fZWidth, "ZWidth/F");
200  fPerFlashTree->Branch("FlashTime", &fFlashTime, "FlashTime/D");
201  fPerFlashTree->Branch("AbsTime", &fAbsTime, "AbsTime/D");
202  fPerFlashTree->Branch("FlashFrame", &fFlashFrame, "FlashFrame/I");
203  fPerFlashTree->Branch("InBeamFrame", &fInBeamFrame, "InBeamFrame/B");
204  fPerFlashTree->Branch("OnBeamTime", &fOnBeamTime, "OnBeamTime/I");
205  fPerFlashTree->Branch("TotalPE", &fTotalPE, "TotalPE/F");
206  }
207 
208  if (fMakePerEventFlashTree) {
209  fPerEventFlashTree = tfs->make<TTree>("PerEventFlashTree", "PerEventFlashTree");
210  fPerEventFlashTree->Branch("EventID", &fEventID, "EventID/I");
211  fPerEventFlashTree->Branch("NFlashes", &fNFlashes, "NFlashes/I");
212  fPerEventFlashTree->Branch("FlashIDVector", &fFlashIDVector);
213  fPerEventFlashTree->Branch("YCenterVector", &fYCenterVector);
214  fPerEventFlashTree->Branch("ZCenterVector", &fZCenterVector);
215  fPerEventFlashTree->Branch("YWidthVector", &fYWidthVector);
216  fPerEventFlashTree->Branch("ZWidthVector", &fZWidthVector);
217  fPerEventFlashTree->Branch("FlashTimeVector", &fFlashTimeVector);
218  fPerEventFlashTree->Branch("AbsTimeVector", &fAbsTimeVector);
219  fPerEventFlashTree->Branch("FlashFrameVector", &fFlashFrameVector);
220  fPerEventFlashTree->Branch("InBeamFrameVector", &fInBeamFrameVector);
221  fPerEventFlashTree->Branch("OnBeamTimeVector", &fOnBeamTimeVector);
222  fPerEventFlashTree->Branch("TotalPEVector", &fTotalPEVector);
223  fPerEventFlashTree->Branch("NChannels", &fNChannels, "NChannels/I");
224  // The only way I can think of to record a two-dimensional variable-size array in a TTree
225  // is by flattening it into a one-dimension variable-size array
226  fPerEventFlashTree->Branch("PEsPerFlashPerChannelVector", &fPEsPerFlashPerChannelVector);
227  }
228 
229  if (fMakeFlashHitMatchTree) {
230  fFlashHitMatchTree = tfs->make<TTree>("FlashHitMatchTree", "FlashHitMatchTree");
231  fFlashHitMatchTree->Branch("EventID", &fEventID, "EventID/I");
232  fFlashHitMatchTree->Branch("FlashID", &fFlashID, "FlashID/I");
233  fFlashHitMatchTree->Branch("HitID", &fHitID, "HitID/I");
234  fFlashHitMatchTree->Branch("OpChannel", &fOpChannel, "OpChannel/I");
235  fFlashHitMatchTree->Branch("HitPeakTimeAbs", &fPeakTimeAbs, "HitPeakTimeAbs/F");
236  fFlashHitMatchTree->Branch("HitPeakTime", &fPeakTime, "HitPeakTime/F");
237  fFlashHitMatchTree->Branch("HitPE", &fPE, "HitPE/F");
238  fFlashHitMatchTree->Branch("FlashPE", &fTotalPE, "FlashPE/F");
239  fFlashHitMatchTree->Branch("FlashTimeAbs", &fAbsTime, "FlashTimeAbs/D");
240  fFlashHitMatchTree->Branch("FlashTime", &fFlashTime, "FlashTime/D");
241  fFlashHitMatchTree->Branch("HitFrame", &fFrame, "HitFrame/I");
242  fFlashHitMatchTree->Branch("FlashFrame", &fFlashFrame, "FlashFrame/I");
243  }
244 
245  fFlashID = 0;
246  }
247 
248  //-----------------------------------------------------------------------
250  {
251 
252  // Get flashes from event
254  evt.getByLabel(fOpFlashModuleLabel, FlashHandle);
255 
256  // Get assosciations between flashes and hits
257  art::FindManyP<recob::OpHit> Assns(FlashHandle, evt, fOpFlashModuleLabel);
258 
259  // Create string for histogram name
260  char HistName[50];
261 
262  fFlashID = 0;
263 
264  // Access ART's TFileService, which will handle creating and writing
265  // histograms for us.
267 
268  std::vector<TH1D*> FlashHist;
269 
270  fEventID = evt.id().event();
271 
272  sprintf(HistName, "Event %d Flash Times", evt.id().event());
273  TH1D* FlashTimes = nullptr;
274  if (fMakeFlashTimeHist) {
275  FlashTimes = tfs->make<TH1D>(HistName,
276  ";t (ns);",
277  int((fTimeEnd - fTimeBegin) * fSampleFreq),
278  fTimeBegin * 1000.,
279  fTimeEnd * 1000.);
280  }
281 
282  TH2D* FlashPositions = nullptr;
283  if (fMakeFlashPosHist) {
284  sprintf(HistName, "Event %d All Flashes YZ", evt.id().event());
285 
286  FlashPositions =
287  tfs->make<TH2D>(HistName, ";y ;z ", PosHistYRes, fYMin, fYMax, PosHistZRes, fZMin, fZMax);
288  }
289 
291  unsigned int NOpChannels = geom->NOpChannels();
292 
294  fNFlashes = FlashHandle->size();
295  fNChannels = NOpChannels;
296  }
297 
298  // For every OpFlash in the vector
299  for (unsigned int i = 0; i < FlashHandle->size(); ++i) {
300 
301  // Get OpFlash
302  art::Ptr<recob::OpFlash> TheFlashPtr(FlashHandle, i);
303  recob::OpFlash TheFlash = *TheFlashPtr;
304 
305  fFlashTime = TheFlash.Time();
306  fFlashID = i; //++;
307 
308  TH2D* ThisFlashPosition = nullptr;
309  if (fMakePerFlashHists) {
310  sprintf(HistName, "Event %d t = %f", evt.id().event(), fFlashTime);
311  FlashHist.push_back(
312  tfs->make<TH1D>(HistName, ";OpChannel;PE", NOpChannels, 0, NOpChannels));
313 
314  sprintf(HistName, "Event %d Flash %f YZ", evt.id().event(), fFlashTime);
315 
316  ThisFlashPosition =
317  tfs->make<TH2D>(HistName, ";y ;z ", PosHistYRes, fYMin, fYMax, PosHistZRes, fZMin, fZMax);
318  }
319  fYCenter = TheFlash.YCenter();
320  fZCenter = TheFlash.ZCenter();
321  fYWidth = TheFlash.YWidth();
322  fZWidth = TheFlash.ZWidth();
323  fInBeamFrame = TheFlash.InBeamFrame();
324  fOnBeamTime = TheFlash.OnBeamTime();
325  fAbsTime = TheFlash.AbsTime();
326  fFlashFrame = TheFlash.Frame();
327  fTotalPE = TheFlash.TotalPE();
328 
330  fFlashIDVector.emplace_back(i);
331  fYCenterVector.emplace_back(TheFlash.YCenter());
332  fZCenterVector.emplace_back(TheFlash.ZCenter());
333  fYWidthVector.emplace_back(TheFlash.YWidth());
334  fZWidthVector.emplace_back(TheFlash.ZWidth());
335  fFlashTimeVector.emplace_back(TheFlash.Time());
336  fAbsTimeVector.emplace_back(TheFlash.AbsTime());
337  fFlashFrameVector.emplace_back(TheFlash.Frame());
338  fInBeamFrameVector.emplace_back(TheFlash.InBeamFrame());
339  fOnBeamTimeVector.emplace_back(TheFlash.OnBeamTime());
340  fTotalPEVector.emplace_back(TheFlash.TotalPE());
341  }
342 
343  for (unsigned int j = 0; j != NOpChannels; ++j) {
344  if (fMakePerFlashHists) FlashHist.at(FlashHist.size() - 1)->Fill(j, TheFlash.PE(j));
345  fNPe = TheFlash.PE(j);
346  fOpChannel = j;
347 
348  if (fMakePerEventFlashTree) fPEsPerFlashPerChannelVector.emplace_back(TheFlash.PE(j));
349 
350  if ((fMakeFlashBreakdownTree) && (fNPe > 0)) fFlashBreakdownTree->Fill();
351  }
352 
353  for (int y = 0; y != PosHistYRes; ++y)
354  for (int z = 0; z != PosHistZRes; ++z) {
355  float ThisY = fYMin + (fYMax - fYMin) * float(y) / PosHistYRes + 0.0001;
356  float ThisZ = fZMin + (fZMax - fZMin) * float(z) / PosHistZRes + 0.0001;
357  if (fMakePerFlashHists)
358  ThisFlashPosition->Fill(ThisY,
359  ThisZ,
360  fTotalPE * exp(-pow((ThisY - fYCenter) / fYWidth, 2) / 2. -
361  pow((ThisZ - fZCenter) / fZWidth, 2) / 2.));
362  if (fMakeFlashPosHist)
363  FlashPositions->Fill(ThisY,
364  ThisZ,
365  fTotalPE * exp(-pow((ThisY - fYCenter) / fYWidth, 2) -
366  pow((ThisZ - fZCenter) / fZWidth, 2)));
367  }
368 
369  if (fMakeFlashTimeHist) FlashTimes->Fill(fFlashTime, fTotalPE);
370 
371  if (fMakePerFlashTree) fPerFlashTree->Fill();
372 
374  // Extract the assosciations
375  fHitID = 0;
376  std::vector<art::Ptr<recob::OpHit>> matchedHits = Assns.at(i);
377  for (auto ophit : matchedHits) {
378  fOpChannel = ophit->OpChannel();
379  fPeakTimeAbs = ophit->PeakTimeAbs();
380  fPeakTime = ophit->PeakTime();
381  fFrame = ophit->Frame();
382  fWidth = ophit->Width();
383  fArea = ophit->Area();
384  fAmplitude = ophit->Amplitude();
385  fPE = ophit->PE();
386  fFastToTotal = ophit->FastToTotal();
387  fFlashHitMatchTree->Fill();
388  fHitID++;
389  }
390  }
391  }
392 
393  if (fMakePerOpHitTree) {
395  evt.getByLabel(fOpHitModuleLabel, OpHitHandle);
396 
397  for (size_t i = 0; i != OpHitHandle->size(); ++i) {
398  fOpChannel = OpHitHandle->at(i).OpChannel();
399  fPeakTimeAbs = OpHitHandle->at(i).PeakTimeAbs();
400  fPeakTime = OpHitHandle->at(i).PeakTime();
401  fFrame = OpHitHandle->at(i).Frame();
402  fWidth = OpHitHandle->at(i).Width();
403  fArea = OpHitHandle->at(i).Area();
404  fAmplitude = OpHitHandle->at(i).Amplitude();
405  fPE = OpHitHandle->at(i).PE();
406  fFastToTotal = OpHitHandle->at(i).FastToTotal();
407  fHitID = i;
408  fPerOpHitTree->Fill();
409  }
410  }
411 
413  fPerEventFlashTree->Fill();
414  fFlashIDVector.clear();
415  fYCenterVector.clear();
416  fZCenterVector.clear();
417  fYWidthVector.clear();
418  fZWidthVector.clear();
419  fFlashTimeVector.clear();
420  fAbsTimeVector.clear();
421  fFlashFrameVector.clear();
422  fInBeamFrameVector.clear();
423  fOnBeamTimeVector.clear();
424  fTotalPEVector.clear();
426  }
427  }
428 
429 } // namespace opdet
430 
431 namespace opdet {
433 }
std::vector< int > fOnBeamTimeVector
std::string fOpHitModuleLabel
OpFlashAna(const fhicl::ParameterSet &)
std::vector< float > fZCenterVector
TNtupleSim Fill(f1, f2, f3, f4)
Float_t y
Definition: compare.C:6
Double_t z
Definition: plot.C:276
std::vector< int > fFlashIDVector
double PE(unsigned int i) const
Definition: OpFlash.h:134
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.cc:6
unsigned int NOpChannels() const
Number of electronics channels for all the optical detectors.
std::vector< bool > fInBeamFrameVector
std::vector< double > fFlashTimeVector
double ZCenter() const
Definition: OpFlash.h:162
double Time() const
Definition: OpFlash.h:118
void analyze(const art::Event &)
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
int OnBeamTime() const
Definition: OpFlash.h:186
unsigned int Frame() const
Definition: OpFlash.h:130
T get(std::string const &key) const
Definition: ParameterSet.h:314
std::vector< int > fFlashFrameVector
std::vector< float > fTotalPEVector
std::vector< double > fAbsTimeVector
double YWidth() const
Definition: OpFlash.h:158
std::vector< float > fPEsPerFlashPerChannelVector
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
std::vector< float > fYWidthVector
std::vector< float > fZWidthVector
EventNumber_t event() const
Definition: EventID.h:116
double TotalPE() const
Definition: OpFlash.cxx:94
TCEvent evt
Definition: DataStructs.cxx:8
double YCenter() const
Definition: OpFlash.h:154
std::vector< float > fYCenterVector
EventID id() const
Definition: Event.cc:23
art framework interface to geometry description
double AbsTime() const
Definition: OpFlash.h:126
double ZWidth() const
Definition: OpFlash.h:166
bool InBeamFrame() const
Definition: OpFlash.h:182
std::string fOpFlashModuleLabel