All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sbndcode/sbndcode/CosmicId/Algs/StoppingParticleCosmicIdAlg.cc
Go to the documentation of this file.
2 
3 namespace sbnd{
4 
6 
7  this->reconfigure(config);
8 
9 }
10 
11 
13 
14 }
15 
16 
18 
19 }
20 
21 
23 
24  fMinX = config.ContainmentCuts().MinX();
25  fMinY = config.ContainmentCuts().MinY();
26  fMinZ = config.ContainmentCuts().MinZ();
27  fMaxX = config.ContainmentCuts().MaxX();
28  fMaxY = config.ContainmentCuts().MaxY();
29  fMaxZ = config.ContainmentCuts().MaxZ();
30  fResRangeMin = config.ResRangeMin();
31  fResRangeMax = config.ResRangeMax();
32  fDEdxMax = config.DEdxMax();
34 
35  return;
36 }
37 
38 // Calculate the chi2 ratio of pol0 and exp fit to dE/dx vs residual range
39 double StoppingParticleCosmicIdAlg::StoppingChiSq(geo::Point_t end, std::vector<art::Ptr<anab::Calorimetry>> calos){
40 
41  // If calorimetry object is null then return 0
42  if(calos.size()==0) return -99999;
43 
44  // Loop over planes (Y->V->U) and choose the next plane's calorimetry if there are 1.5x more points (collection plane more reliable)
45  size_t nhits = 0;
46  art::Ptr<anab::Calorimetry> calo = calos[0];
47  for( size_t i = calos.size(); i > 0; i--){
48  if(calos[i-1]->dEdx().size() > nhits*1.5){
49  nhits = calos[i-1]->dEdx().size();
50  calo = calos[i-1];
51  }
52  }
53 
54  // If there's something wrong with the calorimetry object return null
55  if(calo->XYZ().size() != nhits || nhits < 1) return -99999;
56 
57  // Get the distance from the track point and the start/end of calo data
58  double distStart = (calo->XYZ()[0] - end).Mag2();
59  double distEnd = (calo->XYZ()[nhits-1] - end).Mag2();
60 
61  double maxDedx = 0;
62  double resrgStart = 0;
63  std::vector<double> v_resrg;
64  std::vector<double> v_dedx;
65  // Loop over plane's calorimetry data
66  for(size_t i = 0; i < nhits; i++){
67  double dedx = calo->dEdx()[i];
68  double resrg = calo->ResidualRange()[i];
69 
70  // Flip the residual range if the track and calo objects don't match up
71  if(distStart < distEnd && calo->ResidualRange()[0] > calo->ResidualRange()[nhits-1]) resrg = calo->ResidualRange()[0] - calo->ResidualRange()[i];
72  if(distStart > distEnd && calo->ResidualRange()[0] < calo->ResidualRange()[nhits-1]) resrg = calo->ResidualRange()[nhits-1] - calo->ResidualRange()[i];
73 
74  // Find the maximum dE/dx within a limit and the corresponding res range
75  if(resrg < fResRangeMin && dedx > maxDedx && dedx < fDEdxMax){
76  maxDedx = dedx;
77  resrgStart = resrg;
78  }
79 
80  }
81 
82  // Loop over it again
83  for(size_t i = 0; i < nhits; i++){
84  double dedx = calo->dEdx()[i];
85  double resrg = calo->ResidualRange()[i];
86 
87  // Flip the residual range if the track and calo objects don't match up
88  if(distStart < distEnd && calo->ResidualRange()[0] > calo->ResidualRange()[nhits-1]) resrg = calo->ResidualRange()[0] - calo->ResidualRange()[i];
89  if(distStart > distEnd && calo->ResidualRange()[0] < calo->ResidualRange()[nhits-1]) resrg = calo->ResidualRange()[nhits-1] - calo->ResidualRange()[i];
90 
91  // Record all dE/dx and residual ranges below limits
92  if(resrg > resrgStart && resrg < resrgStart + fResRangeMax && dedx < fDEdxMax){
93  v_resrg.push_back(resrg);
94  v_dedx.push_back(dedx);
95  }
96  }
97 
98  // Return null value if not enough points to do fits
99  if(v_dedx.size() < 10) return -99999;
100 
101  // Try to do a pol0 fit
102  TGraph *gdedx = new TGraph(v_dedx.size(), &v_resrg[0], &v_dedx[0]);
103  try{ gdedx->Fit("pol0", "Q"); } catch(...){ return -99999; }
104  TF1* polfit = gdedx->GetFunction("pol0");
105  double polchi2 = polfit->GetChisquare();
106 
107  // Try to do and exp fit
108  try{ gdedx->Fit("expo", "Q"); } catch(...){ return -99999; }
109  TF1* expfit = gdedx->GetFunction("expo");
110  double expchi2 = expfit->GetChisquare();
111 
112  // Return the chi2 ratio
113  return polchi2/expchi2;
114 
115 }
116 
117 
118 // Determine if the track end looks like it stops
119 bool StoppingParticleCosmicIdAlg::StoppingEnd(geo::Point_t end, std::vector<art::Ptr<anab::Calorimetry>> calos){
120 
121  // Get the chi2 ratio
122  double chiSqRatio = StoppingChiSq(end, calos);
123 
124  // If it is below a limit then tag it as stopping
125  if(chiSqRatio > fStoppingChi2Limit) return true;
126 
127  return false;
128 }
129 
130 // Determine if a track looks like a stopping cosmic
132 
133  // Check if start and end of track is inside the fiducial volume
134  bool startInFiducial = fTpcGeo.InFiducial(track.Vertex(), fMinX, fMinY, fMinZ, fMaxX, fMaxY, fMaxZ);
135  bool endInFiducial = fTpcGeo.InFiducial(track.End(), fMinX, fMinY, fMinZ, fMaxX, fMaxY, fMaxZ);
136 
137  // Check if the start and end of track stops
138  bool startStops = StoppingEnd(track.Vertex(), calos);
139  bool endStops = StoppingEnd(track.End(), calos);
140 
141  // If one end stops and the other end is outside of the FV then tag as stopping cosmic if the track is going downwards
142  if((startStops && !endInFiducial && track.End().Y() > track.Vertex().Y())
143  || (endStops && !startInFiducial && track.Vertex().Y() > track.End().Y())){
144  return true;
145  }
146 
147  return false;
148 
149 }
150 
151 // Determine if two tracks look like a stopping cosmic if they are merged
152 bool StoppingParticleCosmicIdAlg::StoppingParticleCosmicId(recob::Track track, recob::Track track2, std::vector<art::Ptr<anab::Calorimetry>> calos, std::vector<art::Ptr<anab::Calorimetry>> calos2){
153 
154  // Assume both tracks start from the same vertex so take end points as new start/end
155  bool startInFiducial = fTpcGeo.InFiducial(track.End(), fMinX, fMinY, fMinZ, fMaxX, fMaxY, fMaxZ);
156  bool endInFiducial = fTpcGeo.InFiducial(track.End(), fMinX, fMinY, fMinZ, fMaxX, fMaxY, fMaxZ);
157 
158  bool startStops = StoppingEnd(track.End(), calos);
159  bool endStops = StoppingEnd(track2.End(), calos2);
160 
161  if((startStops && !endInFiducial && track2.End().Y() > 0)
162  || (endStops && !startInFiducial && track.End().Y() > 0)){
163  return true;
164  }
165 
166  return false;
167 
168 }
169 
170 
171 }
bool StoppingEnd(geo::Point_t end, std::vector< art::Ptr< anab::Calorimetry >> calos)
process_name use argoneut_mc_hitfinder track
double StoppingChiSq(geo::Point_t end, std::vector< art::Ptr< anab::Calorimetry >> calos)
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
bool StoppingParticleCosmicId(recob::Track track, std::vector< art::Ptr< anab::Calorimetry >> calos)
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
Point_t const & End() const
stream1 can override from command line with o or output services user sbnd
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
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a &quot;fitted&quot; track:
bool InFiducial(geo::Point_t point, double fiducial)