LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
PhotonCounterT0Matching_module.cc
Go to the documentation of this file.
1 
32 // Framework includes
44 
46 #include "fhiclcpp/ParameterSet.h"
48 
49 #include <memory>
50 #include <iostream>
51 #include <map>
52 #include <iterator>
53 
54 // LArSoft
70 //#include "larsim/MCCheater/BackTrackerService.h" //No BackTracker functions are actually used in this module (all commented out.
71 // #include "larsim/MCCheater/ParticleInventoryService.h"
75 
76 // ROOT
77 #include "TTree.h"
78 #include "TFile.h"
79 #include "TH1D.h"
80 #include "TH2D.h"
81 
82 namespace lbne {
84 }
85 
87 public:
88  explicit PhotonCounterT0Matching(fhicl::ParameterSet const & p);
89  // The destructor generated by the compiler is fine for classes
90  // without bare pointers or other resource use.
91 
92  // Plugins should not be copied or assigned.
97 
98  // Required functions.
99  void produce(art::Event & e) override;
100 
101  // Selected optional functions.
102  void beginJob() override;
103  void reconfigure(fhicl::ParameterSet const & p) ;
104 
105 
106 private:
107  // Internal functions.....
108  void TrackProp ( double TrackStart_X, double TrackEnd_X, double &TrackLength_X, double &TrackCentre_X,
109  double TrackStart_Y, double TrackEnd_Y, double &TrackLength_Y, double &TrackCentre_Y,
110  double TrackStart_Z, double TrackEnd_Z, double &TrackLength_Z, double &TrackCentre_Z,
111  double trkTimeStart, double trkTimeEnd, double &trkTimeLengh , double &trkTimeCentre,
112  double &TrackLength);
113  double DistFromPoint ( double StartY, double EndY, double StartZ, double EndZ, double PointY, double PointZ );
114 
115  // Params got from fcl file.......
116  std::string fTrackModuleLabel;
117  std::string fShowerModuleLabel;
118  std::string fHitsModuleLabel;
119  std::string fFlashModuleLabel;
120  std::string fTruthT0ModuleLabel;
122  double fPredictedXPower = 1;
128  double fPEThreshold;
130 
131  // Variables used in module.......
133  double TrackLength_Y, TrackCentre_Y /* , BestTrackCentre_Y */;
134  double TrackLength_Z, TrackCentre_Z /* , BestTrackCentre_Z */;
136 
148 
149  double YZSep, MCTruthT0;
150  // Histograms in TFS branches
151  TTree* fTree;
152  TH2D* hPredX_T;
153  TH2D* hPredX_PE;
154  TH2D* hPredX_T_PE;
161 };
162 
163 
165 // :
166 // Initialize member data here, if know don't want to reconfigure on the fly
167 {
168  // Call appropriate produces<>() functions here.
169  produces< std::vector<anab::T0> >();
170  produces< art::Assns<recob::Track , anab::T0> >();
171  produces< art::Assns<recob::Shower, anab::T0> > ();
172  reconfigure(p);
173 }
174 
176 {
177  // Implementation of optional member function here.
178  fTrackModuleLabel = (p.get< std::string > ("TrackModuleLabel" ) );
179  fShowerModuleLabel = (p.get< std::string > ("ShowerModuleLabel") );
180  fHitsModuleLabel = (p.get< std::string > ("HitsModuleLabel" ) );
181  fFlashModuleLabel = (p.get< std::string > ("FlashModuleLabel" ) );
182  fTruthT0ModuleLabel = (p.get< std::string > ("TruthT0ModuleLabel"));
183 
184  fPredictedXConstant = (p.get< double > ("PredictedXConstant" ) );
185  fPredictedExpConstant = (p.get< double > ("PredictedExpConstant" ) );
186  fPredictedExpGradient = (p.get< double > ("PredictedExpGradient" ) );
187 
188  fDriftWindowSize = (p.get< double > ("DriftWindowSize" ) );
189  fWeightOfDeltaYZ = (p.get< double > ("WeightOfDeltaYZ" ) );
190  fMatchCriteria = (p.get< double > ("MatchCriteria" ) );
191  fPEThreshold = (p.get< double > ("PEThreshold" ) );
192 
193  fVerbosity = (p.get< bool > ("Verbose",false) );
194 }
195 
197 {
198  // Implementation of optional member function here.
200  fTree = tfs->make<TTree>("PhotonCounterT0Matching","PhotonCounterT0");
201  fTree->Branch("TrackCentre_X",&BestTrackCentre_X,"TrackCentre_X/D");
202  fTree->Branch("PredictedX" ,&BestPredictedX ,"PredictedX/D");
203  fTree->Branch("TrackTimeCent",&BesttrkTimeCentre,"TimeSepPredX/D");
204  fTree->Branch("FlashTime" ,&BestFlashTime ,"FlashTime/D");
205  fTree->Branch("TimeSep" ,&BestTimeSep ,"TimeSep/D");
206  fTree->Branch("TimeSepPredX" ,&BestTimeSepPredX ,"TimeSepPredX/D");
207  fTree->Branch("minYZSep" ,&BestminYZSep ,"minYZSep/D");
208  fTree->Branch("FitParam" ,&BestFitParam ,"FitParam/D");
209  fTree->Branch("MCTruthT0" ,&MCTruthT0 ,"MCTruthT0/D");
210 
211  hPredX_T = tfs->make<TH2D>("hPredX_T" ,"Predicted X from timing information against reconstructed X; Reconstructed X (cm); Predicted X (cm)", 30, 0, 300, 30, 0, 300 );
212  hPredX_PE = tfs->make<TH2D>("hPredX_PE","Predicted X from PE information against reconstructed X; Reconstructed X (cm); Predicted X (cm)" , 30, 0, 300, 30, 0, 300 );
213  hPredX_T_PE = tfs->make<TH2D>("hPredX_T_PE",
214  "Predicted X position from time and PE information; Predicted X from timing information (cm); Predicted X from PE information",
215  60, 0, 300, 60, 0, 300);
216  hdeltaX_deltaYZ = tfs->make<TH2D>("hdeltaX_deltaYZ",
217  "Difference between X predicted from PE's and T agaisnt distance of flash from track in YZ; Difference in X predicted from PE's and T (cm); Distance of flash from track in YZ (cm)",
218  40, 0, 200, 40, 0, 100);
219  hdeltaYZ_Length = tfs->make<TH2D>("hdeltaYZ_Length",
220  "Distance of flash from track against track length; Distance from flash to track (cm); Track length (cm)",
221  20, 0, 100, 60, 0, 300);
222  hFitParam_Length = tfs->make<TH2D>("hFitParam_Length", "How fit correlates with track length; Fit correlation; Track Length (cm)", 50, 0, 250, 30, 0, 300);
223  hPhotonT0_MCT0 = tfs->make<TH2D>("hPhotonT0_MCT0" , "Comparing Photon Counter reconstructed T0 against MCTruth T0; Photon Counter T0 (us); MCTruthT0 T0 (us)", 1760, -1600, 16000, 1760, -1600, 16000);
224  hT0_diff_full = tfs->make<TH1D>("hT0_diff_full" , "Difference between MCTruth T0 and photon detector T0; Time difference (us); Number", 500, -2500, 2500);
225  hT0_diff_zoom = tfs->make<TH1D>("hT0_diff_zoom" , "Difference between MCTruth T0 and photon detector T0; Time difference (us); Number", 320, -1.6, 1.6);
226 }
227 
229 {
230  // Access art services...
232  auto const* detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
233  auto const* timeservice = lar::providerFrom<detinfo::DetectorClocksService>();
234  //Commenting this out since it doesn't appear to actually be used.
235 // art::ServiceHandle<cheat::BackTrackerService> bt_serv;
236 
237  //TrackList handle
238  art::Handle< std::vector<recob::Track> > trackListHandle;
239  std::vector<art::Ptr<recob::Track> > tracklist;
240  if (evt.getByLabel(fTrackModuleLabel,trackListHandle))
241  art::fill_ptr_vector(tracklist, trackListHandle);
242 
243  //ShowerList handle
244  art::Handle< std::vector<recob::Shower> > showerListHandle;
245  std::vector<art::Ptr<recob::Shower> > showerlist;
246  if (evt.getByLabel(fShowerModuleLabel,showerListHandle))
247  art::fill_ptr_vector(showerlist, showerListHandle);
248 
249  //HitList Handle
250  art::Handle< std::vector<recob::Hit> > hitListHandle;
251  std::vector<art::Ptr<recob::Hit> > hitlist;
252  if (evt.getByLabel(fHitsModuleLabel,hitListHandle))
253  art::fill_ptr_vector(hitlist, hitListHandle);
254 
255  //FlashList Handle
257  std::vector<art::Ptr<recob::OpFlash> > flashlist;
258  if (evt.getByLabel(fFlashModuleLabel, flashListHandle))
259  art::fill_ptr_vector(flashlist, flashListHandle);
260 
261  // Create anab::T0 objects and make association with recob::Track
262 
263  std::unique_ptr< std::vector<anab::T0> > T0col( new std::vector<anab::T0>);
264  std::unique_ptr< art::Assns<recob::Track, anab::T0> > Trackassn( new art::Assns<recob::Track, anab::T0>);
265  std::unique_ptr< art::Assns<recob::Shower, anab::T0> > Showerassn( new art::Assns<recob::Shower, anab::T0>);
266 
267  if (trackListHandle.isValid() && flashListHandle.isValid() ){
268  //Access tracks and hits
269  art::FindManyP<recob::Hit> fmtht(trackListHandle, evt, fTrackModuleLabel);
270  art::FindMany<anab::T0> fmtruth(trackListHandle, evt, fTruthT0ModuleLabel);
271 
272  size_t NTracks = tracklist.size();
273  size_t NFlashes = flashlist.size();
274 
275  if (fVerbosity)
276  std::cout << "There were " << NTracks << " tracks and " << NFlashes << " flashes in this event." << std::endl;
277 
278  // Now to access PhotonCounter for each track...
279  for(size_t iTrk=0; iTrk < NTracks; ++iTrk) {
280  if (fVerbosity) std::cout << "\n New Track " << (int)iTrk << std::endl;
281  // Reset Variables.
284  bool ValidTrack = false;
285 
286  // Work out Properties of the track.
287  recob::Track::Point_t trackStart, trackEnd;
288  std::tie(trackStart, trackEnd) = tracklist[iTrk]->Extent();
289  std::vector< art::Ptr<recob::Hit> > allHits = fmtht.at(iTrk);
290  size_t nHits = allHits.size();
291  trkTimeStart = allHits[nHits-1]->PeakTime() / timeservice->TPCClock().Frequency(); //Got in ticks, now in us!
292  trkTimeEnd = allHits[0]->PeakTime() / timeservice->TPCClock().Frequency(); //Got in ticks, now in us!
293  TrackProp ( trackStart.X(), trackEnd.X(), TrackLength_X, TrackCentre_X,
294  trackStart.Y(), trackEnd.Y(), TrackLength_Y, TrackCentre_Y,
295  trackStart.Z(), trackEnd.Z(), TrackLength_Z, TrackCentre_Z,
296  trkTimeStart , trkTimeEnd , trkTimeLengh , trkTimeCentre, // times in us!
297  TrackLength);
298 
299  // Some cout statement about track properties.
300  if (fVerbosity) {
301  std::cout << trackStart.X() << " " << trackEnd.X() << " " << TrackLength_X << " " << TrackCentre_X
302  << "\n" << trackStart.Y() << " " << trackEnd.Y() << " " << TrackLength_Y << " " << TrackCentre_Y
303  << "\n" << trackStart.Z() << " " << trackEnd.Z() << " " << TrackLength_Z << " " << TrackCentre_Z
304  << "\n" << trkTimeStart << " " << trkTimeEnd << " " << trkTimeLengh << " " << trkTimeCentre
305  << std::endl;
306  }
307  // ----- Loop over flashes ------
308  for ( size_t iFlash=0; iFlash < NFlashes; ++iFlash ) {
309  //Reset some flash specific quantities
310  YZSep = minYZSep = 9999;
311  FlashTime = TimeSep = 9999;
313  // Check flash could be caused by track...
314  FlashTime = flashlist[iFlash]->Time(); // Got in us!
315  TimeSep = trkTimeCentre - FlashTime; // Time in us!
316  if ( TimeSep < 0 || TimeSep > (fDriftWindowSize/timeservice->TPCClock().Frequency() ) ) continue; // Times compared in us!
317 
318  // Check flash has enough PE's to satisfy our threshold
319  if ( flashlist[iFlash]->TotalPE() < fPEThreshold ) continue;
320 
321  // Work out some quantities for this flash...
322  // PredictedX = ( A / x^n ) + exp ( B + Cx )
323  PredictedX = (fPredictedXConstant / pow ( flashlist[iFlash]->TotalPE(), fPredictedXPower ) ) + ( exp ( fPredictedExpConstant + ( fPredictedExpGradient * flashlist[iFlash]->TotalPE() ) ) );
324  TimeSepPredX = TimeSep * detprop->DriftVelocity(); // us * cm/us = cm!
326  // Dependant on each point...
327  for ( size_t Point = 1; Point < tracklist[iTrk]->NumberTrajectoryPoints(); ++Point ) {
328  TVector3 NewPoint = tracklist[iTrk]->LocationAtPoint(Point);
329  TVector3 PrevPoint = tracklist[iTrk]->LocationAtPoint(Point-1);
330  YZSep = DistFromPoint ( NewPoint[1], PrevPoint[1], NewPoint[2], PrevPoint[2],
331  flashlist[iFlash]->YCenter(), flashlist[iFlash]->ZCenter());
332  if ( Point == 1 ) minYZSep = YZSep;
333  if ( YZSep < minYZSep ) minYZSep = YZSep;
334  }
335 
336  // Determine how well matched this track is......
338  else if (fMatchCriteria == 1) FitParam = minYZSep;
339  else if (fMatchCriteria == 2) FitParam = DeltaPredX;
340 
341  //----FLASH INFO-----
342  if (fVerbosity) {
343  std::cout << "\nFlash " << (int)iFlash << " " << TrackCentre_X << ", " << TimeSepPredX << " - " << PredictedX << " = "
344  << DeltaPredX << ", " << minYZSep << " -> " << FitParam << std::endl;
345  }
346  //----Select best flash------
347  //double YFitRegion = (-1 * DeltaPredX ) + 80;
348  //if ( minYZSep > YFitRegion ) continue;
349  if ( FitParam < BestFitParam ) {
350  ValidTrack = true;
351  BestFlash = (int)iFlash;
360  BestFlashTime = FlashTime;
362  } // Find best Flash
363  } // Loop over Flashes
364 
365  // ---- Now Make association and fill TTree/Histos with the best matched flash.....
366  if (ValidTrack) {
367 
368  // -- Fill Histos --
375  // ------ Compare Photon Matched to MCTruth Matched -------
376  if ( fmtruth.isValid() ) {
377  std::vector<const anab::T0*> T0s = fmtruth.at((int)iTrk);
378  for ( size_t i=0; i<T0s.size(); ++i) {
379  MCTruthT0 = T0s[i]->Time() / 1e3; // Got in ns, now in us!!
380  hPhotonT0_MCT0 ->Fill( BestFlashTime, MCTruthT0 );
381  hT0_diff_full -> Fill( MCTruthT0 - BestFlashTime );
382  hT0_diff_zoom -> Fill( MCTruthT0 - BestFlashTime );
383  //std::cout << "Size " << T0s.size() << " " << MCTruthT0 << " " << BestFlashTime << std::endl;
384  }
385  }
386  // -- Fill TTree --
387  fTree->Fill();
388  //Make Association
389  T0col->push_back(anab::T0(BestFlashTime * 1e3,
391  (int)BestFlash,
392  (*T0col).size(),
394  ));
395  util::CreateAssn(*this, evt, *T0col, tracklist[iTrk], *Trackassn);
396  } // Valid Track
397  } // Loop over tracks
398  }
399  /* // ------------------------------------------------- SHOWER STUFF -------------------------------------------------
400  if (showerListHandle.isValid()){
401  art::FindManyP<recob::Hit> fmsht(showerListHandle,evt, fShowerModuleLabel);
402  // Now Loop over showers....
403  size_t NShowers = showerlist.size();
404  for (size_t Shower = 0; Shower < NShowers; ++Shower) {
405  ShowerMatchID = 0;
406  ShowerID = 0;
407  ShowerT0 = 0;
408  std::vector< art::Ptr<recob::Hit> > allHits = fmsht.at(Shower);
409 
410  std::map<int,double> showeride;
411  for(size_t h = 0; h < allHits.size(); ++h){
412  art::Ptr<recob::Hit> hit = allHits[h];
413  std::vector<sim::IDE> ides;
414  std::vector<sim::TrackIDE> TrackIDs = bt->HitToTrackID(hit);
415 
416  for(size_t e = 0; e < TrackIDs.size(); ++e){
417  showeride[TrackIDs[e].trackID] += TrackIDs[e].energy;
418  }
419  }
420  // Work out which IDE despoited the most charge in the hit if there was more than one.
421  double maxe = -1;
422  double tote = 0;
423  for (std::map<int,double>::iterator ii = showeride.begin(); ii!=showeride.end(); ++ii){
424  tote += ii->second;
425  if ((ii->second)>maxe){
426  maxe = ii->second;
427  ShowerID = ii->first;
428  }
429  }
430  // Now have MCParticle trackID corresponding to shower, so get PdG code and T0 etc.
431  const simb::MCParticle *particle = bt->TrackIDToParticle(ShowerID);
432  ShowerT0 = particle->T();
433  ShowerID = particle->TrackId();
434  ShowerTriggerType = 1; // Using PhotonCounter as trigger, so tigger type is 1.
435 
436  T0col->push_back(anab::T0(ShowerT0,
437  ShowerTriggerType,
438  ShowerID,
439  (*T0col).size()
440  ));
441  util::CreateAssn(*this, evt, *T0col, showerlist[Shower], *Showerassn);
442  }// Loop over showers
443  }
444  */
445  evt.put(std::move(T0col));
446  evt.put(std::move(Trackassn));
447  evt.put(std::move(Showerassn));
448 
449 } // Produce
450 // ----------------------------------------------------------------------------------------------------------------------------
451 void lbne::PhotonCounterT0Matching::TrackProp ( double TrackStart_X, double TrackEnd_X, double &TrackLength_X, double &TrackCentre_X,
452  double TrackStart_Y, double TrackEnd_Y, double &TrackLength_Y, double &TrackCentre_Y,
453  double TrackStart_Z, double TrackEnd_Z, double &TrackLength_Z, double &TrackCentre_Z,
454  double trkTimeStart, double trkTimeEnd, double &trkTimeLengh , double &trkTimeCentre,
455  double &TrackLength) {
457  TrackLength_X = fabs ( TrackEnd_X - TrackStart_X );
458  if ( TrackStart_X < TrackEnd_X ) TrackCentre_X = TrackStart_X + 0.5*TrackLength_X;
459  else TrackCentre_X = TrackStart_X - 0.5*TrackLength_X;
460 
461  TrackLength_Y = fabs ( TrackEnd_Y - TrackStart_Y );
462  if ( TrackStart_Y < TrackEnd_Y ) TrackCentre_Y = TrackStart_Y + 0.5*TrackLength_Y;
463  else TrackCentre_Y = TrackStart_Y - 0.5*TrackLength_Y;
464 
465  TrackLength_Z = fabs ( TrackEnd_Z - TrackStart_Z );
466  if ( TrackStart_Z < TrackEnd_Z ) TrackCentre_Z = TrackStart_Z + 0.5*TrackLength_Z;
467  else TrackCentre_Z = TrackStart_Z - 0.5*TrackLength_Z;
468 
469  trkTimeLengh = trkTimeEnd - trkTimeStart;
470  trkTimeCentre = trkTimeStart + 0.5*trkTimeLengh;
471 
472  TrackLength = pow( pow((TrackEnd_X-TrackStart_X), 2) + pow((TrackEnd_Y-TrackStart_Y), 2) + pow((TrackEnd_Z-TrackStart_Z), 2) , 0.5);
473 
474  return;
475 }
476 // ----------------------------------------------------------------------------------------------------------------------------
477 double lbne::PhotonCounterT0Matching::DistFromPoint ( double StartY, double EndY, double StartZ, double EndZ, double PointY, double PointZ ) {
479  double Length = hypot ( fabs( EndY - StartY), fabs ( EndZ - StartZ ) );
480  // double distance = (double)((point.x - line_start.x) * (line_end.y - line_start.y) - (point.y - line_start.y) * (line_end.x - line_start.x)) / normalLength;
481  double distance = ( (PointZ - StartZ) * (EndY - StartY) - (PointY - StartY) * (EndZ - StartZ) ) / Length;
482  return fabs(distance);
483 }
484 // ----------------------------------------------------------------------------------------------------------------------------
486 
Declaration of signal hit object.
TNtupleSim Fill(f1, f2, f3, f4)
Definition: T0.h:19
Particle class.
double DistFromPoint(double StartY, double EndY, double StartZ, double EndZ, double PointY, double PointZ)
void reconfigure(fhicl::ParameterSet const &p)
ProductID put(std::unique_ptr< PROD > &&product)
Definition: Event.h:102
bool isValid() const
Definition: Handle.h:190
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:42
std::tuple< double, double, const reco::ClusterHit3D * > Point
Definitions used by the VoronoiDiagram algorithm.
Definition: DCEL.h:34
T get(std::string const &key) const
Definition: ParameterSet.h:231
bool CreateAssn(PRODUCER const &prod, art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t indx=UINT_MAX)
Creates a single one-to-one association.
void TrackProp(double TrackStart_X, double TrackEnd_X, double &TrackLength_X, double &TrackCentre_X, double TrackStart_Y, double TrackEnd_Y, double &TrackLength_Y, double &TrackCentre_Y, double TrackStart_Z, double TrackEnd_Z, double &TrackLength_Z, double &TrackCentre_Z, double trkTimeStart, double trkTimeEnd, double &trkTimeLengh, double &trkTimeCentre, double &TrackLength)
Provides recob::Track data product.
Encapsulate the geometry of a wire.
T * make(ARGS...args) const
Utility object to perform functions of association.
Encapsulate the construction of a single detector plane.
PhotonCounterT0Matching(fhicl::ParameterSet const &p)
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
tracking::Point_t Point_t
Definition: Track.h:55
PhotonCounterT0Matching & operator=(PhotonCounterT0Matching const &)=delete
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:464
Float_t e
Definition: plot.C:34
art framework interface to geometry description