ShowerTrajPointdEdx_tool.cc
Go to the documentation of this file.
1 //############################################################################
2 //### Name: ShowerTrajPointdEdx ###
3 //### Author: Dominic Barker (dominic.barker@sheffield.ac.uk) ###
4 //### Date: 13.05.19 ###
5 //### Description: Tool for finding the dEdx of the start track of the ###
6 //### shower using the standard calomitry module. This ###
7 //### takes the sliding fit trajectory to make a 3D dEdx. ###
8 //### This module is best used with the sliding linear fit ###
9 //### and ShowerTrackTrajToSpacePoint ###
10 //############################################################################
11 
12 //Framework Includes
14 
15 //LArSoft Includes
20 
21 namespace ShowerRecoTools {
22 
24 
25  public:
27 
28  //Physics Function. Calculate the dEdx.
29  int CalculateElement(const art::Ptr<recob::PFParticle>& pfparticle,
31  reco::shower::ShowerElementHolder& ShowerEleHolder) override;
32 
33  void FinddEdxLength(std::vector<double>& dEdx_vec, std::vector<double>& dEdx_val);
34 
35  private:
36  //Servcies and Algorithms
39 
40  //fcl parameters
41  float fMinAngleToWire; //Minimum angle between the wire direction and the shower
42  //direction for the spacepoint to be used. Default means
43  //the cut has no effect. In radians.
44  float fShapingTime; //Shaping time of the ASIC defualt so we don't cut on track
45  //going too much into the plane. In Microseconds
46  float fMinDistCutOff; //Distance in wires a hit has to be from the start position
47  //to be used
48  float fMaxDist, MaxDist; //Distance in wires a that a trajectory point can be from a
49  //spacepoint to match to it.
51  dEdxTrackLength; //Max Distance a spacepoint can be away from the start of the
52  //track. In cm
53  float fdEdxCut;
54  bool fUseMedian; //Use the median value as the dEdx rather than the mean.
55  bool fCutStartPosition; //Remove hits using MinDistCutOff from the vertex as well.
56 
57  bool fT0Correct; // Whether to look for a T0 associated to the PFP
58  bool fSCECorrectPitch; // Whether to correct the "squeezing" of pitch, requires corrected input
59  bool
60  fSCECorrectEField; // Whether to use the local electric field, from SpaceChargeService, in recombination calc.
61  bool
62  fSCEInputCorrected; // Whether the input has already been corrected for spatial SCE distortions
63 
65  int fVerbose;
66 
73  };
74 
76  : IShowerTool(pset.get<fhicl::ParameterSet>("BaseTools"))
77  , fCalorimetryAlg(pset.get<fhicl::ParameterSet>("CalorimetryAlg"))
78  , fMinAngleToWire(pset.get<float>("MinAngleToWire"))
79  , fShapingTime(pset.get<float>("ShapingTime"))
80  , fMinDistCutOff(pset.get<float>("MinDistCutOff"))
81  , fMaxDist(pset.get<float>("MaxDist"))
82  , fdEdxTrackLength(pset.get<float>("dEdxTrackLength"))
83  , fdEdxCut(pset.get<float>("dEdxCut"))
84  , fUseMedian(pset.get<bool>("UseMedian"))
85  , fCutStartPosition(pset.get<bool>("CutStartPosition"))
86  , fT0Correct(pset.get<bool>("T0Correct"))
87  , fSCECorrectPitch(pset.get<bool>("SCECorrectPitch"))
88  , fSCECorrectEField(pset.get<bool>("SCECorrectEField"))
89  , fSCEInputCorrected(pset.get<bool>("SCEInputCorrected"))
90  , fPFParticleLabel(pset.get<art::InputTag>("PFParticleLabel"))
91  , fVerbose(pset.get<int>("Verbose"))
92  , fShowerStartPositionInputLabel(pset.get<std::string>("ShowerStartPositionInputLabel"))
93  , fInitialTrackSpacePointsInputLabel(pset.get<std::string>("InitialTrackSpacePointsInputLabel"))
94  , fInitialTrackInputLabel(pset.get<std::string>("InitialTrackInputLabel"))
95  , fShowerdEdxOutputLabel(pset.get<std::string>("ShowerdEdxOutputLabel"))
96  , fShowerBestPlaneOutputLabel(pset.get<std::string>("ShowerBestPlaneOutputLabel"))
97  , fShowerdEdxVecOutputLabel(pset.get<std::string>("ShowerdEdxVecOutputLabel"))
98  {
100  throw cet::exception("ShowerTrajPointdEdx")
101  << "Can only correct for SCE if input is already corrected" << std::endl;
102  }
103  }
104 
105  int
107  art::Event& Event,
108  reco::shower::ShowerElementHolder& ShowerEleHolder)
109  {
110 
111  MaxDist = fMaxDist;
113 
114  // Shower dEdx calculation
115  if (!ShowerEleHolder.CheckElement(fShowerStartPositionInputLabel)) {
116  if (fVerbose)
117  mf::LogError("ShowerTrajPointdEdx") << "Start position not set, returning " << std::endl;
118  return 1;
119  }
120  if (!ShowerEleHolder.CheckElement(fInitialTrackSpacePointsInputLabel)) {
121  if (fVerbose)
122  mf::LogError("ShowerTrajPointdEdx")
123  << "Initial Track Spacepoints is not set returning" << std::endl;
124  return 1;
125  }
126  if (!ShowerEleHolder.CheckElement(fInitialTrackInputLabel)) {
127  if (fVerbose) mf::LogError("ShowerTrajPointdEdx") << "Initial Track is not set" << std::endl;
128  return 1;
129  }
130 
131  //Get the initial track hits
132  std::vector<art::Ptr<recob::SpacePoint>> tracksps;
133  ShowerEleHolder.GetElement(fInitialTrackSpacePointsInputLabel, tracksps);
134 
135  if (tracksps.empty()) {
136  if (fVerbose)
137  mf::LogWarning("ShowerTrajPointdEdx") << "no spacepointsin the initial track" << std::endl;
138  return 0;
139  }
140 
141  // Get the spacepoints
142  auto const spHandle = Event.getValidHandle<std::vector<recob::SpacePoint>>(fPFParticleLabel);
143 
144  // Get the hits associated with the space points
145  const art::FindManyP<recob::Hit>& fmsp =
146  ShowerEleHolder.GetFindManyP<recob::Hit>(spHandle, Event, fPFParticleLabel);
147 
148  //Only consider hits in the same tpcs as the vertex.
149  TVector3 ShowerStartPosition = {-999, -999, -999};
150  ShowerEleHolder.GetElement(fShowerStartPositionInputLabel, ShowerStartPosition);
151  geo::TPCID vtxTPC = fGeom->FindTPCAtPosition(ShowerStartPosition);
152 
153  //Get the initial track
154  recob::Track InitialTrack;
155  ShowerEleHolder.GetElement(fInitialTrackInputLabel, InitialTrack);
156 
157  double pfpT0Time(0); // If no T0 found, assume the particle happened at trigger time (0)
158  if (fT0Correct) {
159  auto const pfpHandle = Event.getValidHandle<std::vector<recob::PFParticle>>(fPFParticleLabel);
160  const art::FindManyP<anab::T0>& fmpfpt0 =
161  ShowerEleHolder.GetFindManyP<anab::T0>(pfpHandle, Event, fPFParticleLabel);
162  std::vector<art::Ptr<anab::T0>> pfpT0Vec = fmpfpt0.at(pfparticle.key());
163  if (pfpT0Vec.size() == 1) { pfpT0Time = pfpT0Vec.front()->Time(); }
164  }
165 
166  //Don't care that I could use a vector.
167  std::map<int, std::vector<double>> dEdx_vec;
168  std::map<int, std::vector<double>> dEdx_vecErr;
169  std::map<int, int> num_hits;
170 
171  for (geo::PlaneID plane_id : fGeom->IteratePlaneIDs()) {
172  dEdx_vec[plane_id.Plane] = {};
173  dEdx_vecErr[plane_id.Plane] = {};
174  num_hits[plane_id.Plane] = 0;
175  }
176 
177  auto const clockData =
179  auto const detProp =
181 
182  //Loop over the spacepoints
183  for (auto const sp : tracksps) {
184 
185  //Get the associated hit
186  std::vector<art::Ptr<recob::Hit>> hits = fmsp.at(sp.key());
187  if (hits.empty()) {
188  if (fVerbose)
189  mf::LogWarning("ShowerTrajPointdEdx")
190  << "no hit for the spacepoint. This suggest the find many is wrong." << std::endl;
191  continue;
192  }
193  const art::Ptr<recob::Hit> hit = hits[0];
194  double wirepitch = fGeom->WirePitch((geo::PlaneID)hit->WireID());
195 
196  //Only consider hits in the same tpc
197  geo::PlaneID planeid = hit->WireID();
198  geo::TPCID TPC = planeid.asTPCID();
199  if (TPC != vtxTPC) { continue; }
200 
201  //Ignore spacepoints within a few wires of the vertex.
203  double dist_from_start = (pos - ShowerStartPosition).Mag();
204 
205  if (fCutStartPosition) {
206  if (dist_from_start < fMinDistCutOff * wirepitch) { continue; }
207 
208  if (dist_from_start > dEdxTrackLength) { continue; }
209  }
210 
211  //Find the closest trajectory point of the track. These should be in order if the user has used ShowerTrackTrajToSpacePoint_tool but the sake of gernicness I'll get the cloest sp.
212  unsigned int index = 999;
213  double MinDist = 999;
214  for (unsigned int traj = 0; traj < InitialTrack.NumberTrajectoryPoints(); ++traj) {
215 
216  geo::Point_t TrajPositionPoint = InitialTrack.LocationAtPoint(traj);
217  TVector3 TrajPosition = {
218  TrajPositionPoint.X(), TrajPositionPoint.Y(), TrajPositionPoint.Z()};
219 
220  //ignore bogus info.
221  auto flags = InitialTrack.FlagsAtPoint(traj);
222  if (flags.isSet(recob::TrajectoryPointFlagTraits::NoPoint)) { continue; }
223 
224  const TVector3 dist = pos - TrajPosition;
225 
226  if (dist.Mag() < MinDist && dist.Mag() < MaxDist * wirepitch) {
227  MinDist = dist.Mag();
228  index = traj;
229  }
230  }
231 
232  //If there is no matching trajectory point then bail.
233  if (index == 999) { continue; }
234 
235  geo::Point_t TrajPositionPoint = InitialTrack.LocationAtPoint(index);
236  TVector3 TrajPosition = {TrajPositionPoint.X(), TrajPositionPoint.Y(), TrajPositionPoint.Z()};
237 
238  geo::Point_t TrajPositionStartPoint = InitialTrack.LocationAtPoint(0);
239  TVector3 TrajPositionStart = {
240  TrajPositionStartPoint.X(), TrajPositionStartPoint.Y(), TrajPositionStartPoint.Z()};
241 
242  //Ignore values with 0 mag from the start position
243  if ((TrajPosition - TrajPositionStart).Mag() == 0) { continue; }
244  if ((TrajPosition - ShowerStartPosition).Mag() == 0) { continue; }
245 
246  if ((TrajPosition - TrajPositionStart).Mag() < fMinDistCutOff * wirepitch) { continue; }
247 
248  //Get the direction of the trajectory point
249  geo::Vector_t TrajDirection_vec = InitialTrack.DirectionAtPoint(index);
250  TVector3 TrajDirection = {
251  TrajDirection_vec.X(), TrajDirection_vec.Y(), TrajDirection_vec.Z()};
252 
253  //If the direction is in the same direction as the wires within some tolerance the hit finding struggles. Let remove these.
254  // Note that we project in the YZ plane to make sure we are not cutting on
255  // the angle into the wire planes, that should be done by the shaping time cut
256  TVector3 TrajDirectionYZ = {0, TrajDirection_vec.Y(), TrajDirection_vec.Z()};
257  TVector3 PlaneDirection = fGeom->Plane(planeid).GetIncreasingWireDirection();
258 
259  if (std::abs((TMath::Pi() / 2 - TrajDirectionYZ.Angle(PlaneDirection))) < fMinAngleToWire) {
260  if (fVerbose) mf::LogWarning("ShowerTrajPointdEdx") << "remove from angle cut" << std::endl;
261  continue;
262  }
263 
264  //If the direction is too much into the wire plane then the shaping amplifer cuts the charge. Lets remove these events.
265  double velocity = detProp.DriftVelocity(detProp.Efield(), detProp.Temperature());
266  double distance_in_x = TrajDirection.X() * (wirepitch / TrajDirection.Dot(PlaneDirection));
267  double time_taken = std::abs(distance_in_x / velocity);
268 
269  //Shaping time doesn't seem to exist in a global place so add it as a fcl.
270  if (fShapingTime < time_taken) {
271  if (fVerbose) mf::LogWarning("ShowerTrajPointdEdx") << "move for shaping time" << std::endl;
272  continue;
273  }
274 
275  if ((TrajPosition - TrajPositionStart).Mag() > dEdxTrackLength) { continue; }
276 
277  //Iterate the number of hits on the plane
278  ++num_hits[planeid.Plane];
279 
280  //If we still exist then we can be used in the calculation. Calculate the 3D pitch
281  double trackpitch = (TrajDirection * (wirepitch / TrajDirection.Dot(PlaneDirection))).Mag();
282 
283  if (fSCECorrectPitch) {
285  trackpitch, pos, TrajDirection.Unit(), hit->WireID().TPC);
286  }
287 
288  //Calculate the dQdx
289  double dQdx = hit->Integral() / trackpitch;
290 
291  //Calculate the dEdx
292  double localEField = detProp.Efield();
293  if (fSCECorrectEField) {
294  localEField = IShowerTool::GetLArPandoraShowerAlg().SCECorrectEField(localEField, pos);
295  }
296  double dEdx = fCalorimetryAlg.dEdx_AREA(
297  clockData, detProp, dQdx, hit->PeakTime(), planeid.Plane, pfpT0Time, localEField);
298 
299  //Add the value to the dEdx
300  dEdx_vec[planeid.Plane].push_back(dEdx);
301  }
302 
303  //Choose max hits based on hitnum
304  int max_hits = 0;
305  int best_plane = -std::numeric_limits<int>::max();
306  for (auto const& [plane, numHits] : num_hits) {
307  if (fVerbose > 2) std::cout << "Plane: " << plane << " with size: " << numHits << std::endl;
308  if (numHits > max_hits) {
309  best_plane = plane;
310  max_hits = numHits;
311  }
312  }
313 
314  if (best_plane < 0) {
315  if (fVerbose)
316  mf::LogError("ShowerTrajPointdEdx") << "No hits in any plane, returning " << std::endl;
317  return 1;
318  }
319 
320  //Search for blow ups and gradient changes.
321  //Electrons have a very flat dEdx as function of energy till ~10MeV.
322  //If there is a sudden jump particle has probably split
323  //If there is very large dEdx we have either calculated it wrong (probably) or the Electron is coming to end.
324  //Assumes hits are ordered!
325  std::map<int, std::vector<double>> dEdx_vec_cut;
326  for (geo::PlaneID plane_id : fGeom->IteratePlaneIDs()) {
327  dEdx_vec_cut[plane_id.Plane] = {};
328  }
329 
330  for (auto& dEdx_plane : dEdx_vec) {
331  FinddEdxLength(dEdx_plane.second, dEdx_vec_cut[dEdx_plane.first]);
332  }
333 
334  //Never have the stats to do a landau fit and get the most probable value. User decides if they want the median value or the mean.
335  std::vector<double> dEdx_val;
336  std::vector<double> dEdx_valErr;
337  for (auto const& dEdx_plane : dEdx_vec_cut) {
338 
339  if ((dEdx_plane.second).empty()) {
340  dEdx_val.push_back(-999);
341  dEdx_valErr.push_back(-999);
342  continue;
343  }
344 
345  if (fUseMedian) {
346  dEdx_val.push_back(TMath::Median((dEdx_plane.second).size(), &(dEdx_plane.second)[0]));
347  }
348  else {
349  //Else calculate the mean value.
350  double dEdx_mean = 0;
351  for (auto const& dEdx : dEdx_plane.second) {
352  if (dEdx > 10 || dEdx < 0) { continue; }
353  dEdx_mean += dEdx;
354  }
355  dEdx_val.push_back(dEdx_mean / (float)(dEdx_plane.second).size());
356  }
357  }
358 
359  if (fVerbose > 1) {
360  std::cout << "#Best Plane: " << best_plane << std::endl;
361  for (unsigned int plane = 0; plane < dEdx_vec.size(); plane++) {
362  std::cout << "#Plane: " << plane << " #" << std::endl;
363  std::cout << "#Median: " << dEdx_val[plane] << " #" << std::endl;
364  if (fVerbose > 2) {
365  for (auto const& dEdx : dEdx_vec_cut[plane]) {
366  std::cout << "dEdx: " << dEdx << std::endl;
367  }
368  }
369  }
370  }
371 
372  //Need to sort out errors sensibly.
373  ShowerEleHolder.SetElement(dEdx_val, dEdx_valErr, fShowerdEdxOutputLabel);
374  ShowerEleHolder.SetElement(best_plane, fShowerBestPlaneOutputLabel);
375  ShowerEleHolder.SetElement(dEdx_vec_cut, fShowerdEdxVecOutputLabel);
376  return 0;
377  }
378 
379  void
380  ShowerTrajPointdEdx::FinddEdxLength(std::vector<double>& dEdx_vec, std::vector<double>& dEdx_val)
381  {
382 
383  //As default do not apply this cut.
384  if (fdEdxCut > 10) {
385  dEdx_val = dEdx_vec;
386  return;
387  }
388 
389  //Can only do this with 4 hits.
390  if (dEdx_vec.size() < 4) {
391  dEdx_val = dEdx_vec;
392  return;
393  }
394 
395  bool upperbound = false;
396 
397  //See if we are in the upper bound or upper bound defined by the cut.
398  int upperbound_int = 0;
399  if (dEdx_vec[0] > fdEdxCut) { ++upperbound_int; }
400  if (dEdx_vec[1] > fdEdxCut) { ++upperbound_int; }
401  if (dEdx_vec[2] > fdEdxCut) { ++upperbound_int; }
402  if (upperbound_int > 1) { upperbound = true; }
403 
404  dEdx_val.push_back(dEdx_vec[0]);
405  dEdx_val.push_back(dEdx_vec[1]);
406  dEdx_val.push_back(dEdx_vec[2]);
407 
408  for (unsigned int dEdx_iter = 2; dEdx_iter < dEdx_vec.size(); ++dEdx_iter) {
409 
410  //The Function of dEdx as a function of E is flat above ~10 MeV.
411  //We are looking for a jump up (or down) above the ladau width in the dEx
412  //to account account for pair production.
413  //Dom Estimates that the somwhere above 0.28 MeV will be a good cut but 999 will prevent this stage.
414  double dEdx = dEdx_vec[dEdx_iter];
415 
416  //We are really poo at physics and so attempt to find the pair production
417  if (upperbound) {
418  if (dEdx > fdEdxCut) {
419  dEdx_val.push_back(dEdx);
420  if (fVerbose > 1) std::cout << "Adding dEdx: " << dEdx << std::endl;
421  continue;
422  }
423  else {
424  //Maybe its a landau fluctation lets try again.
425  if (dEdx_iter < dEdx_vec.size() - 1) {
426  if (dEdx_vec[dEdx_iter + 1] > fdEdxCut) {
427  if (fVerbose > 1)
428  std::cout << "Next dEdx hit is good removing hit" << dEdx << std::endl;
429  continue;
430  }
431  }
432  //I'll let one more value
433  if (dEdx_iter < dEdx_vec.size() - 2) {
434  if (dEdx_vec[dEdx_iter + 2] > fdEdxCut) {
435  if (fVerbose > 1)
436  std::cout << "Next Next dEdx hit is good removing hit" << dEdx << std::endl;
437  continue;
438  }
439  }
440  //We are hopefully we have one of our electrons has died.
441  break;
442  }
443  }
444  else {
445  if (dEdx < fdEdxCut) {
446  dEdx_val.push_back(dEdx);
447  if (fVerbose > 1) std::cout << "Adding dEdx: " << dEdx << std::endl;
448  continue;
449  }
450  else {
451  //Maybe its a landau fluctation lets try again.
452  if (dEdx_iter < dEdx_vec.size() - 1) {
453  if (dEdx_vec[dEdx_iter + 1] > fdEdxCut) {
454  if (fVerbose > 1)
455  std::cout << "Next dEdx hit is good removing hit " << dEdx << std::endl;
456  continue;
457  }
458  }
459  //I'll let one more value
460  if (dEdx_iter < dEdx_vec.size() - 2) {
461  if (dEdx_vec[dEdx_iter + 2] > fdEdxCut) {
462  if (fVerbose > 1)
463  std::cout << "Next Next dEdx hit is good removing hit " << dEdx << std::endl;
464  continue;
465  }
466  }
467  //We are hopefully in the the pair production zone.
468  break;
469  }
470  }
471  }
472  return;
473  }
474 
475 }
476 
double SCECorrectPitch(double const &pitch, TVector3 const &pos, TVector3 const &dir, unsigned int const &TPC) const
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
PlaneGeo const & Plane(unsigned int const p, unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified wire.
static constexpr Flag_t NoPoint
The trajectory point is not defined.
std::string string
Definition: nybbler.cc:12
geo::WireID WireID() const
Definition: Hit.h:233
Point_t const & LocationAtPoint(size_t i) const
Definition: Track.h:126
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
void SetElement(T &dataproduct, const std::string &Name, bool checktag=false)
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
Definition: Track.h:102
STL namespace.
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
Definition: Hit.h:224
const art::FindManyP< T1 > & GetFindManyP(const art::ValidHandle< std::vector< T2 > > &handle, const art::Event &evt, const art::InputTag &moduleTag)
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
Definition: geo_vectors.h:164
Definition: T0.h:16
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
art::ServiceHandle< geo::Geometry > fGeom
Vector GetIncreasingWireDirection() const
Returns the direction of increasing wires.
Definition: PlaneGeo.h:457
double SCECorrectEField(double const &EField, TVector3 const &pos) const
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
IteratorBox< plane_id_iterator,&GeometryCore::begin_plane_id,&GeometryCore::end_plane_id > IteratePlaneIDs() const
Enables ranged-for loops on all plane IDs of the detector.
geo::TPCID FindTPCAtPosition(double const worldLoc[3]) const
Returns the ID of the TPC at specified location.
T abs(T value)
double dEdx(float dqdx, float Efield)
Definition: doAna.cpp:21
key_type key() const noexcept
Definition: Ptr.h:216
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
bool CheckElement(const std::string &Name) const
static int max(int a, int b)
The data type to uniquely identify a TPC.
Definition: geo_types.h:386
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:493
int GetElement(const std::string &Name, T &Element) const
int CalculateElement(const art::Ptr< recob::PFParticle > &pfparticle, art::Event &Event, reco::shower::ShowerElementHolder &ShowerEleHolder) override
Detector simulation of raw signals on wires.
const shower::LArPandoraShowerAlg & GetLArPandoraShowerAlg() const
Definition: IShowerTool.h:87
constexpr TPCID const & asTPCID() const
Conversion to TPCID (for convenience of notation).
Definition: geo_types.h:446
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
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:218
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
Definition: types.h:32
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
Provides recob::Track data product.
double dEdx_AREA(detinfo::DetectorClocksData const &clock_data, detinfo::DetectorPropertiesData const &det_prop, recob::Hit const &hit, double pitch, double T0=0) const
void FinddEdxLength(std::vector< double > &dEdx_vec, std::vector< double > &dEdx_val)
PointFlags_t const & FlagsAtPoint(size_t i) const
Definition: Track.h:118
Vector_t DirectionAtPoint(size_t i) const
Definition: Track.h:134
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:48
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:406
int bool
Definition: qglobal.h:345
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
Definition: Track.h:49
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)
ShowerTrajPointdEdx(const fhicl::ParameterSet &pset)
TVector3 SpacePointPosition(art::Ptr< recob::SpacePoint > const &sp) const