All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CRTTrackRecoAna_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: CRTTrackRecoAna
3 // Module Type: analyzer
4 // File: CRTTrackRecoAna_module.cc
5 //
6 // Analysis module for evaluating CRT track reconstruction on through going
7 // muons.
8 //
9 // Tom Brooks (tbrooks@fnal.gov)
10 ////////////////////////////////////////////////////////////////////////
11 
12 // sbndcode includes
18 
19 // LArSoft includes
22 #include "nusimdata/SimulationBase/MCParticle.h"
23 
24 // Framework includes
25 #include "art/Framework/Core/EDAnalyzer.h"
26 #include "art/Framework/Principal/Event.h"
27 #include "art/Framework/Principal/Handle.h"
28 #include "art/Framework/Services/Registry/ServiceHandle.h"
29 #include "art_root_io/TFileService.h"
30 #include "art/Framework/Core/ModuleMacros.h"
31 #include "canvas/Persistency/Common/FindManyP.h"
33 
34 
35 // Utility libraries
36 #include "messagefacility/MessageLogger/MessageLogger.h"
37 #include "fhiclcpp/ParameterSet.h"
38 #include "fhiclcpp/types/Table.h"
39 #include "fhiclcpp/types/Atom.h"
40 
41 // ROOT includes. Note: To look up the properties of the ROOT classes,
42 // use the ROOT web site; e.g.,
43 // <https://root.cern.ch/doc/master/annotated.html>
44 #include "TH1.h"
45 #include "TH2.h"
46 #include "TVector3.h"
47 
48 // C++ includes
49 #include <map>
50 #include <vector>
51 #include <string>
52 #include <cmath>
53 #include <algorithm>
54 
55 namespace sbnd {
56 
57  class CRTTrackRecoAna : public art::EDAnalyzer {
58  public:
59 
60  // Describes configuration parameters of the module
61  struct Config {
62  using Name = fhicl::Name;
63  using Comment = fhicl::Comment;
64 
65  // One Atom for each parameter
66  fhicl::Atom<art::InputTag> SimModuleLabel {
67  Name("SimModuleLabel"),
68  Comment("tag of detector simulation data product")
69  };
70 
71  fhicl::Atom<art::InputTag> CRTHitLabel {
72  Name("CRTHitLabel"),
73  Comment("tag of CRT hit data product")
74  };
75 
76  fhicl::Atom<art::InputTag> CRTTrackLabel {
77  Name("CRTTrackLabel"),
78  Comment("tag of CRT track data product")
79  };
80 
81  fhicl::Atom<bool> Verbose {
82  Name("Verbose"),
83  Comment("Print information about what's going on")
84  };
85 
86  fhicl::Atom<bool> VeryVerbose {
87  Name("VeryVerbose"),
88  Comment("Print detailed information about every track")
89  };
90 
91  fhicl::Atom<bool> Plot {
92  Name("Plot"),
93  Comment("Plot tracks")
94  };
95 
96  fhicl::Atom<int> PlotTrackID {
97  Name("PlotTrackID"),
98  Comment("ID of track to plot")
99  };
100 
101  fhicl::Table<CRTEventDisplay::Config> Evd {
102  Name("Evd"),
103  };
104 
105  fhicl::Table<CRTBackTracker::Config> CrtBackTrack {
106  Name("CrtBackTrack"),
107  };
108 
109  }; // Config
110 
111  using Parameters = art::EDAnalyzer::Table<Config>;
112 
113  // Constructor: configures module
114  explicit CRTTrackRecoAna(Parameters const& config);
115 
116  // Called once, at start of the job
117  virtual void beginJob() override;
118 
119  // Called once per event
120  virtual void analyze(const art::Event& event) override;
121 
122  // Called once, at end of the job
123  virtual void endJob() override;
124 
125  private:
126 
127  // fcl file parameters
128  art::InputTag fSimModuleLabel; ///< name of detsim producer
129  art::InputTag fCRTHitLabel; ///< name of CRT hit producer
130  art::InputTag fCRTTrackLabel; ///< name of CRT track producer
131  bool fVerbose; ///< print information about what's going on
132  bool fVeryVerbose; ///< print more information about what's going on
133  bool fPlot; ///< plot tracks
134  int fPlotTrackID; ///< id of track to plot
135 
136  // n-tuples
137  std::map<std::string, TH1D*> hTrackDist;
138 
139  std::map<std::string, TH1D*> hCrossDistance;
140 
141  std::map<std::string, TH1D*> hEffMomTotal;
142  std::map<std::string, TH1D*> hEffMomReco;
143  std::map<std::string, TH1D*> hEffThetaTotal;
144  std::map<std::string, TH1D*> hEffThetaReco;
145  std::map<std::string, TH1D*> hEffPhiTotal;
146  std::map<std::string, TH1D*> hEffPhiReco;
147 
148  TH1D* hTime;
149  TH1D* hTime2;
150  TH1D* hX1;
151  TH1D* hX2;
152  TH1D* hY1;
153  TH1D* hY2;
154  TH1D* hZ1;
155  TH1D* hZ2;
156 
157  // Other variables shared between different methods.
159 
162 
163  }; // class CRTTrackRecoAna
164 
165  // Constructor
167  : EDAnalyzer(config)
168  , fSimModuleLabel (config().SimModuleLabel())
169  , fCRTHitLabel (config().CRTHitLabel())
170  , fCRTTrackLabel (config().CRTTrackLabel())
171  , fVerbose (config().Verbose())
172  , fVeryVerbose (config().VeryVerbose())
173  , fPlot (config().Plot())
174  , fPlotTrackID (config().PlotTrackID())
175  , evd (config().Evd())
176  , fCrtBackTrack (config().CrtBackTrack())
177  {
178 
179  }
180 
182  {
183  // Access tfileservice to handle creating and writing histograms
184  art::ServiceHandle<art::TFileService> tfs;
185  // Define histograms
186  for(size_t i = 0; i < fCrtGeo.NumTaggers()+1; i++){
187  std::string tagger = "All";
188  if(i < fCrtGeo.NumTaggers()) tagger = fCrtGeo.GetTagger(i).name;
189  hCrossDistance[tagger] = tfs->make<TH1D>(Form("CrossDistance_%s", tagger.c_str()), "", 40, 0, 100);
190  hTrackDist[tagger] = tfs->make<TH1D>(Form("TrackDist_%s", tagger.c_str()), "", 40, 0, 200);
191 
192  hEffMomTotal[tagger] = tfs->make<TH1D>(Form("EffMomTotal_%s", tagger.c_str()), "", 20, 0, 10);
193  hEffMomReco[tagger] = tfs->make<TH1D>(Form("EffMomReco_%s", tagger.c_str()), "", 20, 0, 10);
194  hEffThetaTotal[tagger] = tfs->make<TH1D>(Form("EffThetaTotal_%s", tagger.c_str()), "", 20, 0, 3.2);
195  hEffThetaReco[tagger] = tfs->make<TH1D>(Form("EffThetaReco_%s", tagger.c_str()), "", 20, 0, 3.2);
196  hEffPhiTotal[tagger] = tfs->make<TH1D>(Form("EffPhiTotal_%s", tagger.c_str()), "", 20, -3.2, 3.2);
197  hEffPhiReco[tagger] = tfs->make<TH1D>(Form("EffPhiReco_%s", tagger.c_str()), "", 20, -3.2, 3.2);
198  }
199  hTime = tfs->make<TH1D>("Time", "", 100, -2000, 4000);
200  hTime2 = tfs->make<TH1D>("Time2", "", 100, -2000, 4000);
201  hX1 = tfs->make<TH1D>("X1", "", 100, -1000, 1000);
202  hX2 = tfs->make<TH1D>("X2", "", 100, -1000, 1000);
203  hY1 = tfs->make<TH1D>("Y1", "", 100, -1000, 1000);
204  hY2 = tfs->make<TH1D>("Y2", "", 100, -1000, 1000);
205  hZ1 = tfs->make<TH1D>("Z1", "", 100, -1000, 1000);
206  hZ2 = tfs->make<TH1D>("Z2", "", 100, -1000, 1000);
207 
208  // Initial output
209  std::cout<<"----------------- CRT Track Reco Ana Module -------------------"<<std::endl;
210 
211  // Take a position that is known to be the center of a strip
212 
213 
214  }// CRTTrackRecoAna::beginJob()
215 
216  void CRTTrackRecoAna::analyze(const art::Event& event)
217  {
218 
219  // Fetch basic event info
220  if(fVerbose){
221  std::cout<<"============================================"<<std::endl
222  <<"Run = "<<event.run()<<", SubRun = "<<event.subRun()<<", Event = "<<event.id().event()<<std::endl
223  <<"============================================"<<std::endl;
224  }
225 
226  //----------------------------------------------------------------------------------------------------------
227  // GETTING PRODUCTS
228  //----------------------------------------------------------------------------------------------------------
229  // Retrieve all the truth info in the events
230  auto particleHandle = event.getValidHandle<std::vector<simb::MCParticle>>(fSimModuleLabel);
231 
232  // Get all the CRT hits
233  auto crtHitHandle = event.getValidHandle<std::vector<sbn::crt::CRTHit>>(fCRTHitLabel);
234 
235  // Get all the CRT tracks
236  auto crtTrackHandle = event.getValidHandle<std::vector<sbn::crt::CRTTrack>>(fCRTTrackLabel);
237 
238  // Get hit to data associations
239  art::FindManyP<sbn::crt::CRTHit> findManyHits(crtTrackHandle, event, fCRTTrackLabel);
240 
241  //----------------------------------------------------------------------------------------------------------
242  // TRUTH MATCHING
243  //----------------------------------------------------------------------------------------------------------
244  std::map<int, std::vector<sbn::crt::CRTTrack>> crtTracks;
245  int trk_i = 0;
246  fCrtBackTrack.Initialize(event);
247  for(auto const& track : (*crtTrackHandle)){
248  int trueId = fCrtBackTrack.TrueIdFromTrackId(event, trk_i);
249  trk_i++;
250  if(trueId == -99999) continue;
251  crtTracks[trueId].push_back(track);
252  }
253 
254  std::map<int, std::vector<sbn::crt::CRTHit>> crtHits;
255  double minHitTime = 99999;
256  double maxHitTime = -99999;
257  int hit_i = 0;
258  for(auto const& hit : (*crtHitHandle)){
259  double hitTime = (double)(int)hit.ts1_ns * 1e-3;
260  if(hitTime < minHitTime) minHitTime = hitTime;
261  if(hitTime > maxHitTime) maxHitTime = hitTime;
262 
263  int trueId = fCrtBackTrack.TrueIdFromHitId(event, hit_i);
264  hit_i++;
265  if(trueId == -99999) continue;
266  crtHits[trueId].push_back(hit);
267  }
268 
269  //----------------------------------------------------------------------------------------------------------
270  // EFFICIENCIES
271  //----------------------------------------------------------------------------------------------------------
272  // Fill a map of true particles
273  std::map<int, simb::MCParticle> particles;
274  for (auto const& particle: (*particleHandle)){
275  int partId = particle.TrackId();
276  particles[partId] = particle;
277 
278  // Only consider particles within the time limit of the generated CRT hits
279  double time = particle.T() * 1e-3;
280  if(time < minHitTime || time > maxHitTime) continue;
281 
282  if(!(std::abs(particle.PdgCode()) == 13 && particle.Mother()==0)) continue;
283 
284  // Only consider particles which generated more than 1 crt hit
285  if(crtHits.find(partId) == crtHits.end()) continue;
286  int nPlanesHit = 0;
287  std::vector<std::string> hitTaggers;
288  for(auto const& hit : crtHits[partId]){
289  if(std::find(hitTaggers.begin(), hitTaggers.end(), hit.tagger) != hitTaggers.end()) continue;
290  hitTaggers.push_back(hit.tagger);
291  nPlanesHit++;
292  }
293  if(nPlanesHit < 2) continue;
294 
295  double momentum = particle.P();
296  TVector3 start (particle.Vx(), particle.Vy(), particle.Vz());
297  TVector3 end (particle.EndX(), particle.EndY(), particle.EndZ());
298  double theta = (end-start).Theta();
299  double phi = (end-start).Phi();
300  for(auto const& tagger : hitTaggers){
301  hEffMomTotal[tagger]->Fill(momentum);
302  hEffThetaTotal[tagger]->Fill(theta);
303  hEffPhiTotal[tagger]->Fill(phi);
304  }
305  hEffMomTotal["All"]->Fill(momentum);
306  hEffThetaTotal["All"]->Fill(theta);
307  hEffPhiTotal["All"]->Fill(phi);
308 
309  if(crtTracks.find(partId) == crtTracks.end()) continue;
310  for(auto const& tagger : hitTaggers){
311  hEffMomReco[tagger]->Fill(momentum);
312  hEffThetaReco[tagger]->Fill(theta);
313  hEffPhiReco[tagger]->Fill(phi);
314  }
315  hEffMomReco["All"]->Fill(momentum);
316  hEffThetaReco["All"]->Fill(theta);
317  hEffPhiReco["All"]->Fill(phi);
318  }
319 
320  //----------------------------------------------------------------------------------------------------------
321  // CRT TRACK ANALYSIS
322  //----------------------------------------------------------------------------------------------------------
323  int track_i = 0;
324  for(auto const& track : (*crtTrackHandle)){
325 
326  hTime->Fill((double)(int)track.ts1_ns*1e-3);
327  hX1->Fill(track.x1_pos);
328  hX2->Fill(track.x2_pos);
329  hY1->Fill(track.y1_pos);
330  hY2->Fill(track.y2_pos);
331  hZ1->Fill(track.z1_pos);
332  hZ2->Fill(track.z2_pos);
333 
334  std::vector<art::Ptr<sbn::crt::CRTHit>> hits = findManyHits.at(track_i);
335 
336  int trueId = fCrtBackTrack.TrueIdFromTrackId(event, track_i);
337  track_i++;
338  if(particles.find(trueId) == particles.end()) continue;
339 
340  // Calculate the average distance over the length of the track
341  TVector3 start {track.x1_pos, track.y1_pos, track.z1_pos};
342  TVector3 end {track.x2_pos, track.y2_pos, track.z2_pos};
343  double denominator = (end - start).Mag();
344 
345  std::vector<double> crtLims = fCrtGeo.CRTLimits();
346  simb::MCParticle particle = particles[trueId];
347 
348  int nTraj = particle.NumberTrajectoryPoints();
349  double aveDCA = 0;
350  double npts = 0;
351  for(int j = 0; j < nTraj; j++){
352  TVector3 pt (particle.Vx(j), particle.Vy(j), particle.Vz(j));
353  if (pt.X() >= crtLims[0] && pt.X() <= crtLims[3] && pt.Y() >= crtLims[1] && pt.Y() <= crtLims[4] && pt.Z() >= crtLims[2] && pt.Z() <= crtLims[5]){
354  double numerator = ((pt - start).Cross(pt - end)).Mag();
355  aveDCA += numerator/denominator;
356  npts++;
357  }
358  }
359 
360  aveDCA = aveDCA/npts;
361 
362  // Find the taggers and positions of the true crossing points
363  sbn::crt::CRTHit startHit, endHit;
364  for(auto const& hit : hits){
365  geo::Point_t trueCross = fCrtGeo.TaggerCrossingPoint(hit->tagger, particles[trueId]);
366  if(trueCross.X() == -99999) continue;
367  // For each tagger calculate the distance between the CRT track and true track
368  double dist = std::sqrt(std::pow(hit->x_pos - trueCross.X(), 2)
369  + std::pow(hit->y_pos - trueCross.Y(), 2)
370  + std::pow(hit->z_pos - trueCross.Z(), 2));
371  hCrossDistance[hit->tagger]->Fill(dist);
372  hCrossDistance["All"]->Fill(dist);
373  hTrackDist[hit->tagger]->Fill(aveDCA);
374  }
375  hTrackDist["All"]->Fill(aveDCA);
376 
377  }
378 
379  if(fPlot){
380  //evd.SetDrawCrtData(true);
381  //evd.SetDrawCrtHits(true);
382  //evd.SetDrawCrtTracks(true);
383  evd.SetDrawTrueTracks(true);
384  if(fVeryVerbose) evd.SetPrint(true);
385  if(fPlotTrackID != -99999) evd.SetTrueId(fPlotTrackID);
386  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(event);
387  evd.Draw(clockData, event);
388  }
389 
390 
391  } // CRTTrackRecoAna::analyze()
392 
394 
395  } // CRTTrackRecoAna::endJob()
396 
397 
398  DEFINE_ART_MODULE(CRTTrackRecoAna)
399 } // namespace sbnd
400 
401 // Back to local namespace.
402 namespace {
403 
404 } // local namespace
fhicl::Atom< art::InputTag > SimModuleLabel
fhicl::Atom< art::InputTag > CRTTrackLabel
BEGIN_PROLOG Verbose
int TrueIdFromTrackId(const art::Event &event, int track_i)
void Draw(detinfo::DetectorClocksData const &clockData, const art::Event &event)
art::InputTag fCRTHitLabel
name of CRT hit producer
CRTTrackRecoAna(Parameters const &config)
std::map< std::string, TH1D * > hCrossDistance
CRTTaggerGeo GetTagger(std::string taggerName) const
virtual void analyze(const art::Event &event) override
art::InputTag fSimModuleLabel
name of detsim producer
process_name use argoneut_mc_hitfinder track
process_name hit
Definition: cheaterreco.fcl:51
std::map< std::string, TH1D * > hEffPhiReco
int TrueIdFromHitId(const art::Event &event, int hit_i)
fhicl::Atom< art::InputTag > CRTHitLabel
T abs(T value)
art::EDAnalyzer::Table< Config > Parameters
virtual void endJob() override
art::InputTag fCRTTrackLabel
name of CRT track producer
int fPlotTrackID
id of track to plot
std::map< std::string, TH1D * > hTrackDist
virtual void beginJob() override
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
std::map< std::string, TH1D * > hEffThetaReco
BEGIN_PROLOG vertical distance to the surface Name
Definition of data types for geometry description.
std::map< std::string, TH1D * > hEffMomTotal
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
geo::Point_t TaggerCrossingPoint(std::string taggerName, const simb::MCParticle &particle)
void SetDrawTrueTracks(bool tf)
bool fVeryVerbose
print more information about what&#39;s going on
std::map< std::string, TH1D * > hEffPhiTotal
do i e
stream1 can override from command line with o or output services user sbnd
art::ServiceHandle< art::TFileService > tfs
fhicl::Table< CRTEventDisplay::Config > Evd
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:184
bool fVerbose
print information about what&#39;s going on
std::map< std::string, TH1D * > hEffThetaTotal
std::map< std::string, TH1D * > hEffMomReco
BEGIN_PROLOG could also be cout
fhicl::Table< CRTBackTracker::Config > CrtBackTrack