All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sbnana/sbnanalysis/ana/SBNOscReco/CosmicIDAlgs/CosmicIdAlg.cc
Go to the documentation of this file.
1 #include "CosmicIdAlg.h"
2 
3 namespace ana{
4 
6 
7  this->reconfigure(config);
8 
9 }
10 
11 
13 
14 }
15 
16 
18 
19 }
20 
21 
22 void CosmicIdAlg::reconfigure(const Config& config){
23 
25  fPandoraLabel = config.PandoraLabel();
29 
38 
47 
51  fMinMergeAngle = config.MinMergeAngle();
52 
53  fvTag = config.FVTagAlg();
54  spTag = config.SPTagAlg();
55  ccTag = config.CCTagAlg();
56  acTag = config.ACTagAlg();
57  chTag = config.CHTagAlg();
58  ctTag = config.CTTagAlg();
59  ptTag = config.PTTagAlg();
60 
61  fBeamTimeMin = config.BeamTimeLimits().BeamTimeMin();
62  fBeamTimeMax = config.BeamTimeLimits().BeamTimeMax();
63 
64  return;
65 }
66 
67 // Change which cuts are run
68 void CosmicIdAlg::SetCuts(bool FV, bool SP, bool Geo, bool CC, bool AC, bool CT, bool CH, bool PT){
69 
70  fApplyFiducialCut = FV;
71  fApplyStoppingCut = SP;
72  fApplyGeometryCut = Geo;
74  fApplyApaCrossCut = AC;
75  fApplyCrtTrackCut = CT;
76  fApplyCrtHitCut = CH;
77  fApplyPandoraT0Cut = PT;
78 
79 }
80 
81 // Reset which cuts are run from fhicl parameters
83 
92 
93 }
94 
95 // Run cuts to decide if track looks like a cosmic
96 bool CosmicIdAlg::CosmicId(recob::Track track, const art::Event& event, std::vector<double> t0Tpc0, std::vector<double> t0Tpc1){
97 
98  // Get associations between tracks and hit collections
99  auto tpcTrackHandle = event.getValidHandle<std::vector<recob::Track>>(fTpcTrackModuleLabel);
100  art::FindManyP<recob::Hit> findManyHits(tpcTrackHandle, event, fTpcTrackModuleLabel);
101  std::vector<art::Ptr<recob::Hit>> hits = findManyHits.at(track.ID());
102  // Get associations between track and calorimetry collections
103  art::FindManyP<anab::Calorimetry> findManyCalo(tpcTrackHandle, event, fCaloModuleLabel);
104 
105  // Tag cosmics from pandora T0 associations
106  if(fApplyPandoraT0Cut){
107  if(ptTag.PandoraT0CosmicId(track, event)) return true;
108  }
109 
110  // Tag cosmics which enter and exit the TPC
111  if(fApplyFiducialCut){
112  if(fvTag.FiducialVolumeCosmicId(track)) return true;
113  }
114 
115  // Tag cosmics which enter the TPC and stop
116  if(fApplyStoppingCut){
117  std::vector<art::Ptr<anab::Calorimetry>> calos = findManyCalo.at(track.ID());
118  if(spTag.StoppingParticleCosmicId(track, calos)) return true;
119  }
120 
121  // Tag cosmics in other TPC to beam activity
122  if(fApplyGeometryCut){
123  bool tpc0Flash = CosmicIdUtils::BeamFlash(t0Tpc0, fBeamTimeMin, fBeamTimeMax);
124  bool tpc1Flash = CosmicIdUtils::BeamFlash(t0Tpc1, fBeamTimeMin, fBeamTimeMax);
125  if(geoTag.GeometryCosmicId(track, hits, tpc0Flash, tpc1Flash)) return true;
126  }
127 
128  // Tag cosmics which cross the CPA
129  if(fApplyCpaCrossCut){
130  std::vector<recob::Track> tracks;
131  for(auto const& tpcTrack : (*tpcTrackHandle)){
132  tracks.push_back(tpcTrack);
133  }
134 
135  if(ccTag.CpaCrossCosmicId(track, tracks, findManyHits)) return true;
136  }
137 
138  // Tag cosmics which cross the APA
139  if(fApplyApaCrossCut){
140  if(acTag.ApaCrossCosmicId(track, hits, t0Tpc0, t0Tpc1)) return true;
141  }
142 
143  // Tag cosmics which match CRT tracks
144  if(fApplyCrtTrackCut){
145  auto crtTrackHandle = event.getValidHandle<std::vector<sbn::crt::CRTTrack>>(_config.CRTTrackTag);
146  std::vector<sbn::crt::CRTTrack> crtTracks = (*crtTrackHandle);
147 
148  if(ctTag.CrtTrackCosmicId(track, crtTracks, event)) return true;
149  }
150 
151  // Tag cosmics which match CRT hits
152  if(fApplyCrtHitCut){
153  auto crtHitHandle = event.getValidHandle<std::vector<sbn::crt::CRTHit>>(fCrtHitModuleLabel);
154  std::vector<sbn::crt::CRTHit> crtHits = (*crtHitHandle);
155 
156  if(chTag.CrtHitCosmicId(track, crtHits, event)) return true;
157  }
158 
159  return false;
160 
161 }
162 
163 // Run cuts to decide if PFParticle looks like a cosmic
164 bool CosmicIdAlg::CosmicId(recob::PFParticle pfparticle, std::map< size_t, art::Ptr<recob::PFParticle> > pfParticleMap, const art::Event& event, std::vector<double> t0Tpc0, std::vector<double> t0Tpc1){
165 
166  // Get associations between pfparticles and tracks
167  art::Handle< std::vector<recob::PFParticle> > pfParticleHandle;
168  event.getByLabel(fPandoraLabel, pfParticleHandle);
169  art::FindManyP< recob::Track > pfPartToTrackAssoc(pfParticleHandle, event, fTpcTrackModuleLabel);
170 
171  // Get associations between tracks and hits/calorimetry collections
172  auto tpcTrackHandle = event.getValidHandle<std::vector<recob::Track>>(fTpcTrackModuleLabel);
173  art::FindManyP<recob::Hit> findManyHits(tpcTrackHandle, event, fTpcTrackModuleLabel);
174  art::FindManyP<anab::Calorimetry> findManyCalo(tpcTrackHandle, event, fCaloModuleLabel);
175 
176  // Loop over all the daughters of the PFParticles and get associated tracks
177  std::vector<recob::Track> nuTracks;
178  for (const size_t daughterId : pfparticle.Daughters()){
179 
180  // Get tracks associated with daughter
181  art::Ptr<recob::PFParticle> pParticle = pfParticleMap.at(daughterId);
182  const std::vector< art::Ptr<recob::Track> > associatedTracks(pfPartToTrackAssoc.at(pParticle.key()));
183  if(associatedTracks.size() != 1) continue;
184 
185  recob::Track track = *associatedTracks.front();
186  nuTracks.push_back(track);
187 
188 
189  }
190 
191  // Tag cosmics from pandora T0 associations
192  if(fApplyPandoraT0Cut){
193  if(ptTag.PandoraT0CosmicId(pfparticle, pfParticleMap, event)) return true;
194  }
195 
196  // Not a cosmic if there are only showers assiciated with PFParticle
197  if(nuTracks.size() == 0) return false;
198 
199  // Sort all daughter tracks by length
200  std::sort(nuTracks.begin(), nuTracks.end(), [](auto& left, auto& right){
201  return left.Length() > right.Length();});
202 
203  // Select longest track as the cosmic candidate
204  recob::Track track = nuTracks[0];
205  std::vector<art::Ptr<recob::Hit>> hits = findManyHits.at(track.ID());
206 
207  // Tag cosmics which enter and exit the TPC
208  if(fApplyFiducialCut){
209  if(fvTag.FiducialVolumeCosmicId(track)) return true;
210  }
211 
212  // Tag cosmics in other TPC to beam activity
213  if(fApplyGeometryCut){
214  bool tpc0Flash = CosmicIdUtils::BeamFlash(t0Tpc0, fBeamTimeMin, fBeamTimeMax);
215  bool tpc1Flash = CosmicIdUtils::BeamFlash(t0Tpc1, fBeamTimeMin, fBeamTimeMax);
216  if(geoTag.GeometryCosmicId(track, hits, tpc0Flash, tpc1Flash)) return true;
217  }
218 
219  // Tag cosmics which match CRT tracks
220  if(fApplyCrtTrackCut){
221  auto crtTrackHandle = event.getValidHandle<std::vector<sbn::crt::CRTTrack>>(fCrtTrackModuleLabel);
222  std::vector<sbn::crt::CRTTrack> crtTracks = (*crtTrackHandle);
223 
224  if(ctTag.CrtTrackCosmicId(track, crtTracks, event)) return true;
225  }
226 
227  // Tag cosmics which cross the CPA
228  if(fApplyCpaCrossCut){
229  std::vector<recob::Track> tracks;
230  for(auto const& tpcTrack : (*tpcTrackHandle)){
231  tracks.push_back(tpcTrack);
232  }
233 
234  if(ccTag.CpaCrossCosmicId(track, tracks, findManyHits)) return true;
235  }
236 
237  // Find second longest particle if trying to merge tracks
238  std::vector<std::pair<recob::Track, double>> secondaryTracks;
239  if(fUseTrackAngleVeto && nuTracks.size() > 1){
240  TVector3 start = track.Vertex<TVector3>();
241  TVector3 end = track.End<TVector3>();
242 
243  // Loop over the secondary tracks
244  // Find smallest angle between primary track and any secondary tracks above a certain length
245  for(size_t i = 1; i < nuTracks.size(); i++){
246  recob::Track track2 = nuTracks[i];
247  // Only consider secondary tracks longer than some limit (try to exclude michel electrons)
248  if(track2.Length() < fMinSecondTrackLength) continue;
249  TVector3 start2 = track2.Vertex<TVector3>();
250  TVector3 end2 = track2.End<TVector3>();
251  // Do they share the same vertex? (no delta rays)
252  if((start-start2).Mag() < fMinVertexDistance){
253  double angle = (end - start).Angle(end2 - start2);
254  secondaryTracks.push_back(std::make_pair(track2, angle));
255  }
256  }
257  }
258 
259  // If there is a valid secondary track
260  if(secondaryTracks.size() > 0){
261  // Sort tracks by smallest angle
262  std::sort(secondaryTracks.begin(), secondaryTracks.end(), [](auto& left, auto& right){
263  return left.second < right.second;});
264  // If secondary track angle is compatible with split track (near 180) then try to merge
265  if(secondaryTracks[0].second > fMinMergeAngle){
266  recob::Track track2 = secondaryTracks[0].first;
267 
268  // Check fiducial volume containment assuming merged track
269  if(fApplyFiducialCut){
270  if(!fvTag.InFiducial(track.End()) && !fvTag.InFiducial(track2.End())) return true;
271  }
272 
273  // Check if stopping applies to merged track
274  if(fApplyStoppingCut){
275  // Apply stopping cut to the longest track
276  std::vector<art::Ptr<anab::Calorimetry>> calos = findManyCalo.at(track.ID());
277  if(spTag.StoppingParticleCosmicId(track, calos)) return true;
278  // Apply stopping cut assuming the tracks are split
279  std::vector<art::Ptr<anab::Calorimetry>> calos2 = findManyCalo.at(track2.ID());
280  if(spTag.StoppingParticleCosmicId(track, track2, calos, calos2)) return true;
281  }
282 
283  // Check if either track crosses APA
284  if(fApplyApaCrossCut){
285  // Apply apa crossing cut to the longest track
286  if(acTag.ApaCrossCosmicId(track, hits, t0Tpc0, t0Tpc1)) return true;
287  // Also apply to secondary track FIXME need to check primary track doesn't go out of bounds
288  std::vector<art::Ptr<recob::Hit>> hits2 = findManyHits.at(track2.ID());
289  if(acTag.ApaCrossCosmicId(track2, hits2, t0Tpc0, t0Tpc1)) return true;
290  }
291 
292  // Check if either track matches CRT hit
293  if(fApplyCrtHitCut){
294  // Apply crt hit match cut to both tracks
295  auto crtHitHandle = event.getValidHandle<std::vector<sbn::crt::CRTHit>>(fCrtHitModuleLabel);
296  std::vector<sbn::crt::CRTHit> crtHits = (*crtHitHandle);
297  if(chTag.CrtHitCosmicId(track, crtHits, event)) return true;
298  if(chTag.CrtHitCosmicId(track2, crtHits, event)) return true;
299  }
300  }
301  // Don't apply other cuts if angle between tracks is consistent with neutrino interaction
302  }
303 
304  // If there's only one track from vertex then apply cuts as normal
305  if(secondaryTracks.size() == 0){
306 
307  // Tag cosmics which enter the TPC and stop
308  if(fApplyStoppingCut){
309  std::vector<art::Ptr<anab::Calorimetry>> calos = findManyCalo.at(track.ID());
310  if(spTag.StoppingParticleCosmicId(track, calos)) return true;
311  }
312 
313  // Tag cosmics which cross the APA
314  if(fApplyApaCrossCut){
315  if(acTag.ApaCrossCosmicId(track, hits, t0Tpc0, t0Tpc1)) return true;
316  }
317 
318  // Tag cosmics which match CRT hits
319  if(fApplyCrtHitCut){
320  auto crtHitHandle = event.getValidHandle<std::vector<sbn::crt::CRTHit>>(fCrtHitModuleLabel);
321  std::vector<sbn::crt::CRTHit> crtHits = (*crtHitHandle);
322 
323  if(chTag.CrtHitCosmicId(track, crtHits, event)) return true;
324  }
325  }
326 
327  return false;
328 
329 }
330 
331 
332 }
bool CrtHitCosmicId(recob::Track track, std::vector< art::Ptr< recob::Hit >> hits, std::vector< sbn::crt::CRTHit > crtHits)
bool CrtTrackCosmicId(recob::Track track, std::vector< art::Ptr< recob::Hit >> hits, std::vector< sbn::crt::CRTTrack > crtTracks)
bool GeometryCosmicId(recob::Track &track, std::vector< art::Ptr< recob::Hit >> &hits, std::map< geo::TPCID, bool > &tpc_flashes)
const std::vector< size_t > & Daughters() const
Returns the collection of daughter particles.
Definition: PFParticle.h:114
ClusterModuleLabel join with tracks
walls no right
Definition: selectors.fcl:105
bool ApaCrossCosmicId(const recob::Track &track, std::vector< art::Ptr< recob::Hit >> &hits, std::map< geo::CryostatID, std::vector< double >> &t_zeros)
process_name use argoneut_mc_hitfinder track
process_name opflashCryoW ana
bool CosmicId(recob::Track track, const art::Event &event, std::vector< double > t0Tpc0, std::vector< double > t0Tpc1)
fhicl::Table< StoppingParticleCosmicIdAlg::Config > SPTagAlg
double Length(size_t p=0) const
Access to various track properties.
fhicl::Table< FiducialVolumeCosmicIdAlg::Config > FVTagAlg
Point_t const & Vertex() const
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
bool BeamFlash(std::vector< double > flashes, double beamTimeMin, double beamTimeMax)
Definition: Util.cc:8
walls no left
Definition: selectors.fcl:105
bool CpaCrossCosmicId(recob::Track track, std::vector< recob::Track > tracks, art::FindManyP< recob::Hit > hitAssoc)
process_name showerreco Particles Coinciding wih the Vertex services ScanOptions nu_mu CC
Hierarchical representation of particle flow.
Definition: PFParticle.h:44
bool PandoraT0CosmicId(recob::Track track, const art::Event &event)
void SetCuts(bool FV, bool SP, bool Geo, bool CC, bool AC, bool CT, bool CH, bool PT)
Point_t const & End() const
finds tracks best matching by angle
bool StoppingParticleCosmicId(recob::Track track, std::vector< art::Ptr< anab::Calorimetry >> calos)
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a &quot;fitted&quot; track: