All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CRTTrackMatchingAna_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: CRTTrackMatchingAnaAna
3 // Module Type: analyzer
4 // File: CRTTrackMatchingAnaAna_module.cc
5 //
6 // Tom Brooks (tbrooks@fnal.gov)
7 ////////////////////////////////////////////////////////////////////////
8 
9 // sbndcode includes
17 
18 // LArSoft includes
25 #include "nusimdata/SimulationBase/MCParticle.h"
26 #include "larcorealg/CoreUtils/NumericUtils.h" // util::absDiff()
27 
28 // Framework includes
29 #include "art/Framework/Core/EDAnalyzer.h"
30 #include "art/Framework/Principal/Event.h"
31 #include "art/Framework/Principal/Handle.h"
32 #include "art/Framework/Services/Registry/ServiceHandle.h"
33 #include "art_root_io/TFileService.h"
34 #include "art/Framework/Core/ModuleMacros.h"
35 #include "canvas/Persistency/Common/FindManyP.h"
36 #include "canvas/Utilities/Exception.h"
39 
40 // Utility libraries
41 #include "messagefacility/MessageLogger/MessageLogger.h"
42 #include "fhiclcpp/ParameterSet.h"
43 #include "fhiclcpp/types/Table.h"
44 #include "fhiclcpp/types/Atom.h"
45 #include "cetlib/pow.h" // cet::sum_of_squares()
46 
47 // ROOT includes. Note: To look up the properties of the ROOT classes,
48 // use the ROOT web site; e.g.,
49 // <https://root.cern.ch/doc/master/annotated.html>
50 #include "TH1.h"
51 #include "TH2.h"
52 #include "TVector3.h"
53 
54 // C++ includes
55 #include <map>
56 #include <vector>
57 #include <string>
58 
59 namespace sbnd {
60 
61  class CRTTrackMatchingAna : public art::EDAnalyzer {
62  public:
63 
64  // Describes configuration parameters of the module
65  struct Config {
66  using Name = fhicl::Name;
67  using Comment = fhicl::Comment;
68 
69  // One Atom for each parameter
70  fhicl::Atom<art::InputTag> SimModuleLabel {
71  Name("SimModuleLabel"),
72  Comment("tag of detector simulation data product")
73  };
74 
75  fhicl::Atom<art::InputTag> CRTTrackLabel {
76  Name("CRTTrackLabel"),
77  Comment("tag of CRT track producer data product")
78  };
79 
80  fhicl::Atom<art::InputTag> TPCTrackLabel {
81  Name("TPCTrackLabel"),
82  Comment("tag of tpc track producer data product")
83  };
84 
85  fhicl::Atom<bool> Verbose {
86  Name("Verbose"),
87  Comment("Print information about what's going on")
88  };
89 
90  fhicl::Table<CRTTrackMatchAlg::Config> CRTTrackAlg {
91  Name("CRTTrackAlg"),
92  };
93 
94  fhicl::Table<CRTBackTracker::Config> CrtBackTrack {
95  Name("CrtBackTrack"),
96  };
97 
98  fhicl::Table<CRTEventDisplay::Config> Evd {
99  Name("Evd"),
100  };
101 
102  }; // Config
103 
104  using Parameters = art::EDAnalyzer::Table<Config>;
105 
106  // Constructor: configures module
107  explicit CRTTrackMatchingAna(Parameters const& config);
108 
109  // Called once, at start of the job
110  virtual void beginJob() override;
111 
112  // Called once per event
113  virtual void analyze(const art::Event& event) override;
114 
115  // Called once, at end of the job
116  virtual void endJob() override;
117 
118  // Calculate the distance from the track crossing point to CRT overlap coordinates
119  double DistToCrtHit(TVector3 trackPos, sbn::crt::CRTHit crtHit);
120 
121  private:
122 
123  // fcl file parameters
124  art::InputTag fSimModuleLabel; ///< name of detsim producer
125  art::InputTag fCRTTrackLabel; ///< name of CRT producer
126  art::InputTag fTPCTrackLabel; ///< name of CRT producer
127  bool fVerbose; ///< print information about what's going on
128 
130 
133 
136 
137  // Histograms
138  TH1D* hAngle;
139  TH1D* hMatchAngle;
141 
142  TH1D* hDCA;
143  TH1D* hMatchDCA;
144  TH1D* hNoMatchDCA;
145 
148 
153 
155  TH1D* hEffDCAReco;
158 
159  }; // class CRTTrackMatchingAna
160 
161 
162  // Constructor
164  : EDAnalyzer(config)
165  , fSimModuleLabel (config().SimModuleLabel())
166  , fCRTTrackLabel (config().CRTTrackLabel())
167  , fTPCTrackLabel (config().TPCTrackLabel())
168  , fVerbose (config().Verbose())
169  , trackAlg (config().CRTTrackAlg())
170  , fCrtBackTrack (config().CrtBackTrack())
171  , evd (config().Evd())
172  {
173 
174  } //CRTTrackMatchingAna()
175 
176 
178  {
179 
180  // Access tfileservice to handle creating and writing histograms
181  art::ServiceHandle<art::TFileService> tfs;
182 
183  hAngle = tfs->make<TH1D>("Angle", "", 50, 0, 2);
184  hMatchAngle = tfs->make<TH1D>("MatchAngle", "", 50, 0, 2);
185  hNoMatchAngle = tfs->make<TH1D>("NoMatchAngle", "", 50, 0, 2);
186 
187  hDCA = tfs->make<TH1D>("DCA", "", 50, 0, 150);
188  hMatchDCA = tfs->make<TH1D>("MatchDCA", "", 50, 0, 150);
189  hNoMatchDCA = tfs->make<TH1D>("NoMatchDCA", "", 50, 0, 150);
190 
191  hMatchAngleDCA = tfs->make<TH2D>("MatchAngleDCA", "", 20, 0, 2, 20, 0, 150);
192  hNoMatchAngleDCA = tfs->make<TH2D>("NoMatchAngleDCA", "", 20, 0, 2, 20, 0, 150);
193 
194  hEffAngleTotal = tfs->make<TH1D>("EffAngleTotal", "", 20, 0, 1);
195  hEffAngleReco = tfs->make<TH1D>("EffAngleReco", "", 20, 0, 1);
196  hPurityAngleTotal = tfs->make<TH1D>("PurityAngleTotal", "", 20, 0, 1);
197  hPurityAngleReco = tfs->make<TH1D>("PurityAngleReco", "", 20, 0, 1);
198 
199  hEffDCATotal = tfs->make<TH1D>("EffDCATotal", "", 20, 0, 100);
200  hEffDCAReco = tfs->make<TH1D>("EffDCAReco", "", 20, 0, 100);
201  hPurityDCATotal = tfs->make<TH1D>("PurityDCATotal", "", 20, 0, 100);
202  hPurityDCAReco = tfs->make<TH1D>("PurityDCAReco", "", 20, 0, 100);
203 
204  // Initial output
205  if(fVerbose) std::cout<<"----------------- CRT T0 Matching Ana Module -------------------"<<std::endl;
206 
207  } // CRTTrackMatchingAna::beginJob()
208 
209 
210  void CRTTrackMatchingAna::analyze(const art::Event& event)
211  {
212 
213  // Fetch basic event info
214  if(fVerbose){
215  std::cout<<"============================================"<<std::endl
216  <<"Run = "<<event.run()<<", SubRun = "<<event.subRun()<<", Event = "<<event.id().event()<<std::endl
217  <<"============================================"<<std::endl;
218  }
219 
220  //----------------------------------------------------------------------------------------------------------
221  // GETTING PRODUCTS
222  //----------------------------------------------------------------------------------------------------------
223 
224  // Get g4 particles
225  auto particleHandle = event.getValidHandle<std::vector<simb::MCParticle>>(fSimModuleLabel);
226 
227  // Get CRT hits from the event
228  art::Handle< std::vector<sbn::crt::CRTTrack>> crtTrackHandle;
229  std::vector<art::Ptr<sbn::crt::CRTTrack> > crtTrackList;
230  if (event.getByLabel(fCRTTrackLabel, crtTrackHandle))
231  art::fill_ptr_vector(crtTrackList, crtTrackHandle);
232 
233  // Get reconstructed tracks from the event
234  auto tpcTrackHandle = event.getValidHandle<std::vector<recob::Track>>(fTPCTrackLabel);
235  art::FindManyP<recob::Hit> findManyHits(tpcTrackHandle, event, fTPCTrackLabel);
236 
237  fCrtBackTrack.Initialize(event);
238 
239  //----------------------------------------------------------------------------------------------------------
240  // TRUTH MATCHING
241  //----------------------------------------------------------------------------------------------------------
242 
243  std::map<int, simb::MCParticle> particles;
244  // Loop over the true particles
245  for (auto const& particle: (*particleHandle)){
246 
247  // Make map with ID
248  int partID = particle.TrackId();
249  particles[partID] = particle;
250 
251  }
252 
253  std::vector<sbn::crt::CRTTrack> crtTracks;
254  std::map<int, std::vector<sbn::crt::CRTTrack>> crtTrackMap;
255  int track_i = 0;
256  double minTrackTime = 99999;
257  double maxTrackTime = -99999;
258 
259  for(auto const& track : (*crtTrackHandle)){
260  crtTracks.push_back(track);
261  int trueID = fCrtBackTrack.TrueIdFromTrackId(event, track_i);
262  track_i++;
263  if(trueID != -99999) crtTrackMap[trueID].push_back(track);
264 
265  double trackTime = (double)(int)track.ts1_ns * 1e-3;
266  if(trackTime < minTrackTime) minTrackTime = trackTime;
267  if(trackTime > maxTrackTime) maxTrackTime = trackTime;
268  }
269 
270  //----------------------------------------------------------------------------------------------------------
271  // ANGLE AND DISTANCE OF CLOSEST APPROACH ANALYSIS
272  //----------------------------------------------------------------------------------------------------------
273 
274  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(event);
275  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(event, clockData);
276 
277  // Loop over reconstructed tracks
278  for (auto const& tpcTrack : (*tpcTrackHandle)){
279  // Get the associated hits
280  std::vector<art::Ptr<recob::Hit>> hits = findManyHits.at(tpcTrack.ID());
281  int trackTrueID = RecoUtils::TrueParticleIDFromTotalRecoHits(clockData, hits, false);
282 
283  if(particles.find(trackTrueID) == particles.end()) continue;
284  // Only consider primary muons
285  if(!(std::abs(particles[trackTrueID].PdgCode()) == 13 && particles[trackTrueID].Mother() == 0)) continue;
286 
287  // Only consider particles withing time window of reco track
288  double trueTime = particles[trackTrueID].T() * 1e-3;
289  if(trueTime < minTrackTime || trueTime > maxTrackTime) continue;
290 
291  //----------------------------------------------------------------------------------------------------------
292  // SINGLE ANGLE CUT ANALYSIS
293  //----------------------------------------------------------------------------------------------------------
294  // Find the closest track by angle
295  std::pair<sbn::crt::CRTTrack, double> closestAngle = trackAlg.ClosestCRTTrackByAngle(detProp,tpcTrack, crtTracks, event);
296  if(closestAngle.second != -99999){
297  hAngle->Fill(closestAngle.second);
298  }
299  // Is crt track matched to that tpc track
300  if(closestAngle.second != -99999){
301  int crtTrueID = fCrtBackTrack.TrueIdFromTotalEnergy(event, closestAngle.first);
302  if(crtTrueID == trackTrueID && crtTrueID != -99999){
303  hMatchAngle->Fill(closestAngle.second);
304  }
305  else{
306  hNoMatchAngle->Fill(closestAngle.second);
307  }
308  }
309 
310  int nbinsAngle = hEffAngleTotal->GetNbinsX();
311  for(int i = 0; i < nbinsAngle; i++){
312  double angleCut = hEffAngleTotal->GetBinCenter(i);
313 
314  // Fill total efficiency histogram with each cut if track matches any hits
315  if(crtTrackMap.find(trackTrueID) != crtTrackMap.end()){
316  hEffAngleTotal->Fill(angleCut);
317 
318  // If closest hit is below limit and track matches any hits then fill efficiency
319  if(closestAngle.second < angleCut && closestAngle.second != -99999){
320  hEffAngleReco->Fill(angleCut);
321  }
322  }
323 
324  // Fill total purity histogram with each cut if closest hit is below limit
325  if(closestAngle.second < angleCut && closestAngle.second != -99999){
326  hPurityAngleTotal->Fill(angleCut);
327 
328  // If closest hit is below limit and matched time is correct then fill purity
329  double trackTime = closestAngle.first.ts1_ns * 1e-3;
330  if(particles.find(trackTrueID) != particles.end()){
331  if(std::abs(trackTime - trueTime) < 2.){
332  hPurityAngleReco->Fill(angleCut);
333  }
334  }
335  }
336  }
337 
338  //----------------------------------------------------------------------------------------------------------
339  // SINGLE DCA CUT ANALYSIS
340  //----------------------------------------------------------------------------------------------------------
341  // Find the closest track by average distance of closest approach
342  std::pair<sbn::crt::CRTTrack, double> closestDCA = trackAlg.ClosestCRTTrackByDCA(detProp,tpcTrack, crtTracks, event);
343  if(closestDCA.second != -99999){
344  hDCA->Fill(closestDCA.second);
345  }
346  if(closestDCA.second != -99999){
347  int crtTrueID = fCrtBackTrack.TrueIdFromTotalEnergy(event, closestDCA.first);
348  if(crtTrueID == trackTrueID && crtTrueID != -99999){
349  hMatchDCA->Fill(closestDCA.second);
350  }
351  else{
352  hNoMatchDCA->Fill(closestDCA.second);
353  }
354  }
355 
356  int nbinsDCA = hEffDCATotal->GetNbinsX();
357  for(int i = 0; i < nbinsDCA; i++){
358  double DCAcut = hEffDCATotal->GetBinCenter(i);
359 
360  // Fill total efficiency histogram with each cut if track matches any hits
361  if(crtTrackMap.find(trackTrueID) != crtTrackMap.end()){
362  hEffDCATotal->Fill(DCAcut);
363 
364  // If closest hit is below limit and track matches any hits then fill efficiency
365  if(closestDCA.second < DCAcut && closestDCA.second != -99999){
366  hEffDCAReco->Fill(DCAcut);
367  }
368  }
369 
370  // Fill total purity histogram with each cut if closest hit is below limit
371  if(closestDCA.second < DCAcut && closestDCA.second != -99999){
372  hPurityDCATotal->Fill(DCAcut);
373 
374  // If closest hit is below limit and matched time is correct then fill purity
375  double trackTime = closestDCA.first.ts1_ns * 1e-3;
376  if(particles.find(trackTrueID) != particles.end()){
377  if(std::abs(trackTime - trueTime) < 2.){
378  hPurityDCAReco->Fill(DCAcut);
379  }
380  }
381  }
382  }
383 
384 
385  //----------------------------------------------------------------------------------------------------------
386  // JOINT DCA AND ANGLE CUT ANALYSIS
387  //----------------------------------------------------------------------------------------------------------
388  std::vector<sbn::crt::CRTTrack> possTracks = trackAlg.AllPossibleCRTTracks(detProp,tpcTrack, crtTracks, event);
389  for(auto const& possTrack : possTracks){
390  int crtTrueID = fCrtBackTrack.TrueIdFromTotalEnergy(event, possTrack);
391  double angle = trackAlg.AngleBetweenTracks(tpcTrack, possTrack);
392  double DCA = trackAlg.AveDCABetweenTracks(detProp, tpcTrack, possTrack, event);
393  if(crtTrueID == trackTrueID && crtTrueID != -99999){
394  hMatchAngleDCA->Fill(angle, DCA);
395  }
396  else{
397  hNoMatchAngleDCA->Fill(angle, DCA);
398  }
399  }
400 
401  }
402 
403  /*
404  evd.SetDrawCrtTracks(true);
405  evd.SetDrawCrtData(true);
406  evd.SetDrawTpcTracks(true);
407  evd.SetDrawTrueTracks(true);
408  evd.SetDrawTpc(true);
409  evd.SetTrueId(114);
410  evd.Draw(event);
411 */
412 
413  } // CRTTrackMatchingAna::analyze()
414 
415 
417 
418 
419  } // CRTTrackMatchingAna::endJob()
420 
421 
422  DEFINE_ART_MODULE(CRTTrackMatchingAna)
423 } // namespace sbnd
BEGIN_PROLOG Verbose
int TrueIdFromTrackId(const art::Event &event, int track_i)
fhicl::Table< CRTTrackMatchAlg::Config > CRTTrackAlg
Functions to help with numbers.
art::InputTag fSimModuleLabel
name of detsim producer
Declaration of signal hit object.
fhicl::Atom< art::InputTag > TPCTrackLabel
fhicl::Table< CRTEventDisplay::Config > Evd
process_name use argoneut_mc_hitfinder track
fhicl::Atom< art::InputTag > CRTTrackLabel
double AngleBetweenTracks(recob::Track tpcTrack, sbn::crt::CRTTrack crtTrack)
double AveDCABetweenTracks(recob::Track tpcTrack, sbn::crt::CRTTrack crtTrack, double shift)
int TrueIdFromTotalEnergy(const art::Event &event, const sbnd::crt::CRTData &data)
T abs(T value)
fhicl::Table< CRTBackTracker::Config > CrtBackTrack
std::pair< sbn::crt::CRTTrack, double > ClosestCRTTrackByDCA(detinfo::DetectorPropertiesData const &detProp, recob::Track tpcTrack, std::vector< sbn::crt::CRTTrack > crtTracks, const art::Event &event, double minAngle=0.)
virtual void analyze(const art::Event &event) override
CRTTrackMatchingAna(Parameters const &config)
art::InputTag fCRTTrackLabel
name of CRT producer
BEGIN_PROLOG vertical distance to the surface Name
int TrueParticleIDFromTotalRecoHits(detinfo::DetectorClocksData const &clockData, const std::vector< art::Ptr< recob::Hit > > &hits, bool rollup_unsaved_ids=1)
fhicl::Atom< art::InputTag > SimModuleLabel
BEGIN_PROLOG don t mess with this TPCTrackLabel
Definition of data types for geometry description.
Provides recob::Track data product.
std::vector< sbn::crt::CRTTrack > AllPossibleCRTTracks(detinfo::DetectorPropertiesData const &detProp, recob::Track tpcTrack, std::vector< sbn::crt::CRTTrack > crtTracks, const art::Event &event)
bool fVerbose
print information about what&#39;s going on
double DistToCrtHit(TVector3 trackPos, sbn::crt::CRTHit crtHit)
std::pair< sbn::crt::CRTTrack, double > ClosestCRTTrackByAngle(detinfo::DetectorPropertiesData const &detProp, recob::Track tpcTrack, std::vector< sbn::crt::CRTTrack > crtTracks, const art::Event &event, double minDCA=0.)
object containing MC truth information necessary for making RawDigits and doing back tracking ...
do i e
art::InputTag fTPCTrackLabel
name of CRT producer
stream1 can override from command line with o or output services user sbnd
finds tracks best matching by angle
art::ServiceHandle< art::TFileService > tfs
BEGIN_PROLOG could also be cout
auto const detProp
art::EDAnalyzer::Table< Config > Parameters