All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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.
22 #include "art/Framework/Core/EDAnalyzer.h"
23 #include "art/Framework/Core/ModuleMacros.h"
24 #include "art/Framework/Principal/Event.h"
25 #include "art/Framework/Principal/Handle.h"
26 #include "art/Framework/Services/Registry/ServiceHandle.h"
27 #include "art_root_io/TFileService.h"
28 #include "canvas/Persistency/Common/FindManyP.h"
29 #include "canvas/Persistency/Common/Ptr.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.
37  OpFlashAna(const fhicl::ParameterSet&);
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
121  OpFlashAna::OpFlashAna(fhicl::ParameterSet const& pset) : EDAnalyzer(pset)
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 =
134  art::ServiceHandle<detinfo::DetectorClocksService const>()->DataForJob();
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 
157  art::ServiceHandle<art::TFileService const> tfs;
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  //-----------------------------------------------------------------------
249  void
250  OpFlashAna::analyze(const art::Event& evt)
251  {
252 
253  // Get flashes from event
254  art::Handle<std::vector<recob::OpFlash>> FlashHandle;
255  evt.getByLabel(fOpFlashModuleLabel, FlashHandle);
256 
257  // Get assosciations between flashes and hits
258  art::FindManyP<recob::OpHit> Assns(FlashHandle, evt, fOpFlashModuleLabel);
259 
260  // Create string for histogram name
261  char HistName[50];
262 
263  fFlashID = 0;
264 
265  // Access ART's TFileService, which will handle creating and writing
266  // histograms for us.
267  art::ServiceHandle<art::TFileService const> tfs;
268 
269  std::vector<TH1D*> FlashHist;
270 
271  fEventID = evt.id().event();
272 
273  sprintf(HistName, "Event %d Flash Times", evt.id().event());
274  TH1D* FlashTimes = nullptr;
275  if (fMakeFlashTimeHist) {
276  FlashTimes = tfs->make<TH1D>(HistName,
277  ";t (ns);",
278  int((fTimeEnd - fTimeBegin) * fSampleFreq),
279  fTimeBegin * 1000.,
280  fTimeEnd * 1000.);
281  }
282 
283  TH2D* FlashPositions = nullptr;
284  if (fMakeFlashPosHist) {
285  sprintf(HistName, "Event %d All Flashes YZ", evt.id().event());
286 
287  FlashPositions =
288  tfs->make<TH2D>(HistName, ";y ;z ", PosHistYRes, fYMin, fYMax, PosHistZRes, fZMin, fZMax);
289  }
290 
291  art::ServiceHandle<geo::Geometry const> geom;
292  unsigned int NOpChannels = geom->NOpChannels();
293 
295  fNFlashes = FlashHandle->size();
296  fNChannels = NOpChannels;
297  }
298 
299  // For every OpFlash in the vector
300  for (unsigned int i = 0; i < FlashHandle->size(); ++i) {
301 
302  // Get OpFlash
303  art::Ptr<recob::OpFlash> TheFlashPtr(FlashHandle, i);
304  recob::OpFlash TheFlash = *TheFlashPtr;
305 
306  fFlashTime = TheFlash.Time();
307  fFlashID = i; //++;
308 
309  TH2D* ThisFlashPosition = nullptr;
310  if (fMakePerFlashHists) {
311  sprintf(HistName, "Event %d t = %f", evt.id().event(), fFlashTime);
312  FlashHist.push_back(
313  tfs->make<TH1D>(HistName, ";OpChannel;PE", NOpChannels, 0, NOpChannels));
314 
315  sprintf(HistName, "Event %d Flash %f YZ", evt.id().event(), fFlashTime);
316 
317  ThisFlashPosition =
318  tfs->make<TH2D>(HistName, ";y ;z ", PosHistYRes, fYMin, fYMax, PosHistZRes, fZMin, fZMax);
319  }
320  fYCenter = TheFlash.YCenter();
321  fZCenter = TheFlash.ZCenter();
322  fYWidth = TheFlash.YWidth();
323  fZWidth = TheFlash.ZWidth();
324  fInBeamFrame = TheFlash.InBeamFrame();
325  fOnBeamTime = TheFlash.OnBeamTime();
326  fAbsTime = TheFlash.AbsTime();
327  fFlashFrame = TheFlash.Frame();
328  fTotalPE = TheFlash.TotalPE();
329 
331  fFlashIDVector.emplace_back(i);
332  fYCenterVector.emplace_back(TheFlash.YCenter());
333  fZCenterVector.emplace_back(TheFlash.ZCenter());
334  fYWidthVector.emplace_back(TheFlash.YWidth());
335  fZWidthVector.emplace_back(TheFlash.ZWidth());
336  fFlashTimeVector.emplace_back(TheFlash.Time());
337  fAbsTimeVector.emplace_back(TheFlash.AbsTime());
338  fFlashFrameVector.emplace_back(TheFlash.Frame());
339  fInBeamFrameVector.emplace_back(TheFlash.InBeamFrame());
340  fOnBeamTimeVector.emplace_back(TheFlash.OnBeamTime());
341  fTotalPEVector.emplace_back(TheFlash.TotalPE());
342  }
343 
344  for (unsigned int j = 0; j != NOpChannels; ++j) {
345  if (fMakePerFlashHists) FlashHist.at(FlashHist.size() - 1)->Fill(j, TheFlash.PE(j));
346  fNPe = TheFlash.PE(j);
347  fOpChannel = j;
348 
349  if (fMakePerEventFlashTree) fPEsPerFlashPerChannelVector.emplace_back(TheFlash.PE(j));
350 
351  if ((fMakeFlashBreakdownTree) && (fNPe > 0)) fFlashBreakdownTree->Fill();
352  }
353 
354  for (int y = 0; y != PosHistYRes; ++y)
355  for (int z = 0; z != PosHistZRes; ++z) {
356  float ThisY = fYMin + (fYMax - fYMin) * float(y) / PosHistYRes + 0.0001;
357  float ThisZ = fZMin + (fZMax - fZMin) * float(z) / PosHistZRes + 0.0001;
358  if (fMakePerFlashHists)
359  ThisFlashPosition->Fill(ThisY,
360  ThisZ,
361  fTotalPE * exp(-pow((ThisY - fYCenter) / fYWidth, 2) / 2. -
362  pow((ThisZ - fZCenter) / fZWidth, 2) / 2.));
363  if (fMakeFlashPosHist)
364  FlashPositions->Fill(ThisY,
365  ThisZ,
366  fTotalPE * exp(-pow((ThisY - fYCenter) / fYWidth, 2) -
367  pow((ThisZ - fZCenter) / fZWidth, 2)));
368  }
369 
370  if (fMakeFlashTimeHist) FlashTimes->Fill(fFlashTime, fTotalPE);
371 
372  if (fMakePerFlashTree) fPerFlashTree->Fill();
373 
375  // Extract the assosciations
376  fHitID = 0;
377  std::vector<art::Ptr<recob::OpHit>> matchedHits = Assns.at(i);
378  for (auto ophit : matchedHits) {
379  fOpChannel = ophit->OpChannel();
380  fPeakTimeAbs = ophit->PeakTimeAbs();
381  fPeakTime = ophit->PeakTime();
382  fFrame = ophit->Frame();
383  fWidth = ophit->Width();
384  fArea = ophit->Area();
385  fAmplitude = ophit->Amplitude();
386  fPE = ophit->PE();
387  fFastToTotal = ophit->FastToTotal();
388  fFlashHitMatchTree->Fill();
389  fHitID++;
390  }
391  }
392  }
393 
394  if (fMakePerOpHitTree) {
395  art::Handle<std::vector<recob::OpHit>> OpHitHandle;
396  evt.getByLabel(fOpHitModuleLabel, OpHitHandle);
397 
398  for (size_t i = 0; i != OpHitHandle->size(); ++i) {
399  fOpChannel = OpHitHandle->at(i).OpChannel();
400  fPeakTimeAbs = OpHitHandle->at(i).PeakTimeAbs();
401  fPeakTime = OpHitHandle->at(i).PeakTime();
402  fFrame = OpHitHandle->at(i).Frame();
403  fWidth = OpHitHandle->at(i).Width();
404  fArea = OpHitHandle->at(i).Area();
405  fAmplitude = OpHitHandle->at(i).Amplitude();
406  fPE = OpHitHandle->at(i).PE();
407  fFastToTotal = OpHitHandle->at(i).FastToTotal();
408  fHitID = i;
409  fPerOpHitTree->Fill();
410  }
411  }
412 
414  fPerEventFlashTree->Fill();
415  fFlashIDVector.clear();
416  fYCenterVector.clear();
417  fZCenterVector.clear();
418  fYWidthVector.clear();
419  fZWidthVector.clear();
420  fFlashTimeVector.clear();
421  fAbsTimeVector.clear();
422  fFlashFrameVector.clear();
423  fInBeamFrameVector.clear();
424  fOnBeamTimeVector.clear();
425  fTotalPEVector.clear();
427  }
428  }
429 
430 } // namespace opdet
431 
432 namespace opdet {
433  DEFINE_ART_MODULE(OpFlashAna)
434 }
process_name opflash particleana ie ie ie z
std::vector< int > fOnBeamTimeVector
std::string fOpHitModuleLabel
OpFlashAna(const fhicl::ParameterSet &)
std::vector< float > fZCenterVector
std::vector< int > fFlashIDVector
double PE(unsigned int i) const
Definition: OpFlash.h:110
std::vector< bool > fInBeamFrameVector
std::vector< double > fFlashTimeVector
double ZCenter() const
Definition: OpFlash.h:117
double Time() const
Definition: OpFlash.h:106
process_name opflash particleana ie ie y
void analyze(const art::Event &)
int OnBeamTime() const
Definition: OpFlash.h:123
unsigned int Frame() const
Definition: OpFlash.h:109
std::vector< int > fFlashFrameVector
std::vector< float > fTotalPEVector
std::vector< double > fAbsTimeVector
double YWidth() const
Definition: OpFlash.h:116
BEGIN_PROLOG opflashCryoW opflashCryoW triggerfilterBNB triggerfilterNuMI triggerfilterOffbeamBNB triggerfilterOffbeamNuMI triggerfilterUnknown roifinder roifinder2d gaushitTPCEE gaushitTPCWE purityana1 ophit
std::vector< float > fPEsPerFlashPerChannelVector
std::vector< float > fYWidthVector
std::vector< float > fZWidthVector
art::ServiceHandle< art::TFileService > tfs
double TotalPE() const
Definition: OpFlash.cxx:68
TCEvent evt
Definition: DataStructs.cxx:8
double YCenter() const
Definition: OpFlash.h:115
std::vector< float > fYCenterVector
art framework interface to geometry description
double AbsTime() const
Definition: OpFlash.h:108
double ZWidth() const
Definition: OpFlash.h:118
bool InBeamFrame() const
Definition: OpFlash.h:122
std::string fOpFlashModuleLabel