All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sbnana/sbnanalysis/ana/SBNOscReco/CosmicIDAlgs/StoppingParticleCosmicIdAlg.cc
Go to the documentation of this file.
2 
3 namespace ana{
4 
6 
7  this->reconfigure(manager, config);
8 
9 }
10 
11 
13 
14 }
15 
16 
18 
19 }
20 
21 
23  fFiducialVolumes.clear();
24 
25  fMinX = config.ContainmentCuts().MinX();
26  fMinY = config.ContainmentCuts().MinY();
27  fMinZ = config.ContainmentCuts().MinZ();
28  fMaxX = config.ContainmentCuts().MaxX();
29  fMaxY = config.ContainmentCuts().MaxY();
30  fMaxZ = config.ContainmentCuts().MaxZ();
31 
32  // get the set of fiducial volumes
33  for (auto const &cryo: manager.GetGeometryProvider()->IterateCryostats()) {
34  geo::GeometryCore::TPC_iterator tstart = manager.GetGeometryProvider()->begin_TPC(cryo.ID()),
35  tend = manager.GetGeometryProvider()->end_TPC(cryo.ID());
36 
37  double Min_X = std::min_element(tstart, tend, [](auto &lhs, auto &rhs) { return lhs.MinX() < rhs.MinX(); })->MinX();
38  double Min_Y = std::min_element(tstart, tend, [](auto &lhs, auto &rhs) { return lhs.MinY() < rhs.MinY(); })->MinY();
39  double Min_Z = std::min_element(tstart, tend, [](auto &lhs, auto &rhs) { return lhs.MinZ() < rhs.MinZ(); })->MinZ();
40 
41  double Max_X = std::max_element(tstart, tend, [](auto &lhs, auto &rhs) { return lhs.MaxX() < rhs.MaxX(); })->MaxX();
42  double Max_Y = std::max_element(tstart, tend, [](auto &lhs, auto &rhs) { return lhs.MaxY() < rhs.MaxY(); })->MaxY();
43  double Max_Z = std::max_element(tstart, tend, [](auto &lhs, auto &rhs) { return lhs.MaxZ() < rhs.MaxZ(); })->MaxZ();
44 
45  fFiducialVolumes.emplace_back(Min_X + fMinX, Max_X - fMaxX, Min_Y + fMinY, Max_Y - fMaxY, Min_Z + fMinZ, Max_Z - fMaxZ);
46  }
47 
48  fResRangeMin = config.ResRangeMin();
49  fResRangeMax = config.ResRangeMax();
50  fDEdxMax = config.DEdxMax();
52 
53  return;
54 }
55 
56 // Calculate the chi2 ratio of pol0 and exp fit to dE/dx vs residual range
57 double StoppingParticleCosmicIdAlg::StoppingChiSq(geo::Point_t end, std::vector<art::Ptr<anab::Calorimetry>> calos){
58 
59  // If calorimetry object is null then return 0
60  if(calos.size()==0) return -99999;
61 
62  // Loop over planes (Y->V->U) and choose the next plane's calorimetry if there are 1.5x more points (collection plane more reliable)
63  size_t nhits = 0;
64  art::Ptr<anab::Calorimetry> calo = calos[0];
65  for( size_t i = calos.size(); i > 0; i--){
66  if(calos[i-1]->dEdx().size() > nhits*1.5){
67  nhits = calos[i-1]->dEdx().size();
68  calo = calos[i-1];
69  }
70  }
71 
72  // If there's something wrong with the calorimetry object return null
73  if(calo->XYZ().size() != nhits || nhits < 1) return -99999;
74 
75  // Get the distance from the track point and the start/end of calo data
76  double distStart = (calo->XYZ()[0] - end).Mag2();
77  double distEnd = (calo->XYZ()[nhits-1] - end).Mag2();
78 
79  double maxDedx = 0;
80  double resrgStart = 0;
81  std::vector<double> v_resrg;
82  std::vector<double> v_dedx;
83  // Loop over plane's calorimetry data
84  for(size_t i = 0; i < nhits; i++){
85  double dedx = calo->dEdx()[i];
86  double resrg = calo->ResidualRange()[i];
87 
88  // Flip the residual range if the track and calo objects don't match up
89  if(distStart < distEnd && calo->ResidualRange()[0] > calo->ResidualRange()[nhits-1]) resrg = calo->ResidualRange()[0] - calo->ResidualRange()[i];
90  if(distStart > distEnd && calo->ResidualRange()[0] < calo->ResidualRange()[nhits-1]) resrg = calo->ResidualRange()[nhits-1] - calo->ResidualRange()[i];
91 
92  // Find the maximum dE/dx within a limit and the corresponding res range
93  if(resrg < fResRangeMin && dedx > maxDedx && dedx < fDEdxMax){
94  maxDedx = dedx;
95  resrgStart = resrg;
96  }
97 
98  }
99 
100  // Loop over it again
101  for(size_t i = 0; i < nhits; i++){
102  double dedx = calo->dEdx()[i];
103  double resrg = calo->ResidualRange()[i];
104 
105  // Flip the residual range if the track and calo objects don't match up
106  if(distStart < distEnd && calo->ResidualRange()[0] > calo->ResidualRange()[nhits-1]) resrg = calo->ResidualRange()[0] - calo->ResidualRange()[i];
107  if(distStart > distEnd && calo->ResidualRange()[0] < calo->ResidualRange()[nhits-1]) resrg = calo->ResidualRange()[nhits-1] - calo->ResidualRange()[i];
108 
109  // Record all dE/dx and residual ranges below limits
110  if(resrg > resrgStart && resrg < resrgStart + fResRangeMax && dedx < fDEdxMax){
111  v_resrg.push_back(resrg);
112  v_dedx.push_back(dedx);
113  }
114  }
115 
116  // Return null value if not enough points to do fits
117  if(v_dedx.size() < 10) return -99999;
118 
119  // Try to do a pol0 fit
120  TGraph *gdedx = new TGraph(v_dedx.size(), &v_resrg[0], &v_dedx[0]);
121  try{ gdedx->Fit("pol0", "Q"); } catch(...){ delete gdedx; return -99999; }
122  TF1* polfit = gdedx->GetFunction("pol0");
123  double polchi2 = polfit->GetChisquare();
124 
125  // Try to do and exp fit
126  try{ gdedx->Fit("expo", "Q"); } catch(...){ delete gdedx; return -99999; }
127  TF1* expfit = gdedx->GetFunction("expo");
128  double expchi2 = expfit->GetChisquare();
129 
130  delete gdedx;
131 
132  // Return the chi2 ratio
133  return polchi2/expchi2;
134 
135 }
136 
137 
138 // Determine if the track end looks like it stops
139 bool StoppingParticleCosmicIdAlg::StoppingEnd(geo::Point_t end, std::vector<art::Ptr<anab::Calorimetry>> calos){
140 
141  // Get the chi2 ratio
142  double chiSqRatio = StoppingChiSq(end, calos);
143 
144  // If it is below a limit then tag it as stopping
145  if(chiSqRatio > fStoppingChi2Limit) return true;
146 
147  return false;
148 }
149 
150 // Check if point in fiducial volume used by this algorithm
152  for (const geo::BoxBoundedGeo vol: fFiducialVolumes) {
153  if (vol.ContainsPosition(point)) return true;
154  }
155  return false;
156 }
157 
158 // Determine if a track looks like a stopping cosmic
160 
161  // Check if start and end of track is inside the fiducial volume
162  bool startInFiducial = InFiducial(track.Vertex());
163  bool endInFiducial = InFiducial(track.End());
164 
165  // Check if the start and end of track stops
166  bool startStops = StoppingEnd(track.Vertex(), calos);
167  bool endStops = StoppingEnd(track.End(), calos);
168 
169  // If one end stops and the other end is outside of the FV then tag as stopping cosmic if the track is going downwards
170  if((startStops && !endInFiducial && track.End().Y() > track.Vertex().Y())
171  || (endStops && !startInFiducial && track.Vertex().Y() > track.End().Y())){
172  return true;
173  }
174 
175  return false;
176 
177 }
178 
179 /*
180 
181 // Determine if two tracks look like a stopping cosmic if they are merged
182 bool StoppingParticleCosmicIdAlg::StoppingParticleCosmicId(recob::Track track, recob::Track track2, std::vector<art::Ptr<anab::Calorimetry>> calos, std::vector<art::Ptr<anab::Calorimetry>> calos2){
183 
184  // Assume both tracks start from the same vertex so take end points as new start/end
185  bool startInFiducial = fTpcGeo.InFiducial(track.End(), fMinX, fMinY, fMinZ, fMaxX, fMaxY, fMaxZ);
186  bool endInFiducial = fTpcGeo.InFiducial(track.End(), fMinX, fMinY, fMinZ, fMaxX, fMaxY, fMaxZ);
187 
188  bool startStops = StoppingEnd(track.End(), calos);
189  bool endStops = StoppingEnd(track2.End(), calos2);
190 
191  if((startStops && !endInFiducial && track2.End().Y() > 0)
192  || (endStops && !startInFiducial && track.End().Y() > 0)){
193  return true;
194  }
195 
196  return false;
197 
198 }*/
199 
200 
201 }
void reconfigure(const core::ProviderManager &manager, const Config &config)
process_name use argoneut_mc_hitfinder track
process_name opflashCryoW ana
const geo::GeometryCore * GetGeometryProvider() const
TPC_iterator begin_TPC() const
Returns an iterator pointing to the first TPC in the detector.
process_name can override from command line with o or output calo
Definition: pid.fcl:40
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
Interface to LArSoft services.
StoppingParticleCosmicIdAlg(const core::ProviderManager &manager, const Config &config)
Point_t const & Vertex() const
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
float dEdx(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const TCSlice &slc, TP3D &tp3d)
Definition: PFPUtils.cxx:2687
IteratorBox< cryostat_iterator,&GeometryCore::begin_cryostat,&GeometryCore::end_cryostat > IterateCryostats() const
Enables ranged-for loops on all cryostats of the detector.
double StoppingChiSq(geo::Point_t end, std::vector< art::Ptr< anab::Calorimetry >> calos)
A base class aware of world box coordinatesAn object describing a simple shape can inherit from this ...
Definition: BoxBoundedGeo.h:33
bool StoppingEnd(geo::Point_t end, std::vector< art::Ptr< anab::Calorimetry >> calos)
Point_t const & End() const
Forward iterator browsing all geometry elements in the detector.
Definition: GeometryCore.h:727
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 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:
TPC_iterator end_TPC() const
Returns an iterator pointing after the last TPC in the detector.