LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
TrackCalorimetryAlg.cxx
Go to the documentation of this file.
1 
10 #include "TrackCalorimetryAlg.h"
11 #include "fhiclcpp/ParameterSet.h"
12 
15 #include "lardata/ArtDataHelper/TrackUtils.h" // lar::util::TrackPitchInView()
21 
23  : caloAlg(p.get<fhicl::ParameterSet>("CalorimetryAlg"))
24 {
25  fNHitsToDetermineStart = p.get<unsigned int>("NHitsToDetermineStart", 3);
26 }
27 
29  detinfo::DetectorClocksData const& clock_data,
30  detinfo::DetectorPropertiesData const& det_prop,
31  std::vector<recob::Track> const& trackVector,
32  std::vector<recob::Hit> const& hitVector,
33  std::vector<std::vector<size_t>> const& hit_indices_per_track,
34  std::vector<anab::Calorimetry>& caloVector,
35  std::vector<size_t>& assnTrackCaloVector,
36  geo::WireReadoutGeom const& wireReadoutGeom)
37 {
38  //loop over the track list
39  for (size_t i_track = 0; i_track < trackVector.size(); i_track++) {
40 
41  recob::Track const& track = trackVector[i_track];
42  std::vector<float> path_length_fraction_vec(CreatePathLengthFractionVector(track));
43 
44  //sort hits into each plane
45  std::vector<std::vector<size_t>> hit_indices_per_plane(wireReadoutGeom.Nplanes());
46  for (auto const& i_hit : hit_indices_per_track[i_track])
47  hit_indices_per_plane[hitVector[i_hit].WireID().Plane].push_back(i_hit);
48 
49  //loop over the planes
50  for (unsigned int i_plane = 0; i_plane < wireReadoutGeom.Nplanes(); ++i_plane) {
51  geo::PlaneID const planeID{0, 0, i_plane};
52 
53  //project down the track into wire/tick space for this plane
54  std::vector<std::pair<geo::WireID, float>> traj_points_in_plane(
55  track.NumberTrajectoryPoints());
56  for (size_t i_trjpt = 0; i_trjpt < track.NumberTrajectoryPoints(); i_trjpt++) {
57  double x_pos = track.LocationAtPoint(i_trjpt).X();
58  float tick = det_prop.ConvertXToTicks(x_pos, (int)i_plane, 0, 0);
59  traj_points_in_plane[i_trjpt] = std::make_pair(
60  wireReadoutGeom.Plane(planeID).NearestWireID(track.LocationAtPoint(i_trjpt)), tick);
61  }
62 
63  HitPropertiesMultiset_t HitPropertiesMultiset;
64  //now loop through hits
65  for (auto const& i_hit : hit_indices_per_plane[i_plane])
66  AnalyzeHit(clock_data,
67  det_prop,
68  hitVector[i_hit],
69  track,
70  traj_points_in_plane,
71  path_length_fraction_vec,
72  HitPropertiesMultiset,
73  wireReadoutGeom);
74 
76  HitPropertiesMultiset, track, i_track, caloVector, assnTrackCaloVector, planeID);
77 
78  } //end loop over planes
79 
80  } //end loop over tracks
81 
82 } //end ExtractCalorimetry
83 
85 public:
86  dist_projected(recob::Hit const& h, geo::WireReadoutGeom const& wireReadoutGeom)
87  : hit(h), wireReadoutGeom(wireReadoutGeom)
88  {}
89  bool operator()(std::pair<geo::WireID, float> const& i, std::pair<geo::WireID, float> const& j)
90  {
91  float dw_i = ((int)(i.first.Wire) - (int)(hit.WireID().Wire)) *
92  wireReadoutGeom.Plane(i.first.asPlaneID()).WirePitch();
93  float dw_j = ((int)(j.first.Wire) - (int)(hit.WireID().Wire)) *
94  wireReadoutGeom.Plane(j.first.asPlaneID()).WirePitch();
95  float dt_i = i.second - hit.PeakTime();
96  float dt_j = j.second - hit.PeakTime();
97  return std::hypot(dw_i, dt_i) < std::hypot(dw_j, dt_j);
98  }
99 
100 private:
101  recob::Hit const& hit;
103 };
104 
106  recob::Track const& track)
107 {
108  std::vector<float> trk_path_length_frac_vec(track.NumberTrajectoryPoints());
109 
110  float cumulative_path_length = 0;
111  const float total_path_length = track.Length();
112  for (size_t i_trj = 1; i_trj < track.NumberTrajectoryPoints(); i_trj++) {
113  cumulative_path_length += (track.LocationAtPoint(i_trj) - track.LocationAtPoint(i_trj - 1)).R();
114  trk_path_length_frac_vec[i_trj] = cumulative_path_length / total_path_length;
115  }
116 
117  return trk_path_length_frac_vec;
118 }
119 
121  detinfo::DetectorClocksData const& clock_data,
122  detinfo::DetectorPropertiesData const& det_prop,
123  recob::Hit const& hit,
124  recob::Track const& track,
125  std::vector<std::pair<geo::WireID, float>> const& traj_points_in_plane,
126  std::vector<float> const& path_length_fraction_vec,
127  HitPropertiesMultiset_t& HitPropertiesMultiset,
128  geo::WireReadoutGeom const& wireReadoutGeom)
129 {
130  size_t traj_iter = std::distance(traj_points_in_plane.begin(),
131  std::min_element(traj_points_in_plane.begin(),
132  traj_points_in_plane.end(),
133  dist_projected(hit, wireReadoutGeom)));
134  float pitch = lar::util::TrackPitchInView(
135  track, wireReadoutGeom.Plane(hit.WireID().asPlaneID()).View(), traj_iter);
136 
137  HitPropertiesMultiset.emplace(hit.Integral(),
138  hit.Integral() / pitch,
139  caloAlg.dEdx_AREA(clock_data, det_prop, hit, pitch),
140  pitch,
141  track.LocationAtPoint<TVector3>(traj_iter),
142  path_length_fraction_vec[traj_iter]);
143 }
144 
146 {
147 
148  if (hpm.size() <= fNHitsToDetermineStart) return false;
149 
150  float charge_start = 0, charge_end = 0;
151  unsigned int counter = 0;
152  for (HitPropertiesMultiset_t::iterator it_hpm = hpm.begin(); it_hpm != hpm.end(); it_hpm++) {
153  charge_start += (*it_hpm).charge;
154  counter++;
155  if (counter == fNHitsToDetermineStart) break;
156  }
157 
158  counter = 0;
159  for (HitPropertiesMultiset_t::reverse_iterator it_hpm = hpm.rbegin(); it_hpm != hpm.rend();
160  it_hpm++) {
161  charge_end += (*it_hpm).charge;
162  counter++;
163  if (counter == fNHitsToDetermineStart) break;
164  }
165 
166  return charge_start > charge_end;
167 }
168 
170  recob::Track const& track,
171  size_t const& i_track,
172  std::vector<anab::Calorimetry>& caloVector,
173  std::vector<size_t>& assnTrackCaloVector,
174  geo::PlaneID const& planeID)
175 {
176  size_t n_hits = hpm.size();
177  std::vector<float> dEdxVector, dQdxVector, resRangeVector, deadWireVector, pitchVector;
178  std::vector<TVector3> XYZVector;
179 
180  dEdxVector.reserve(n_hits);
181  dQdxVector.reserve(n_hits);
182  resRangeVector.reserve(n_hits);
183  deadWireVector.reserve(n_hits);
184  pitchVector.reserve(n_hits);
185  XYZVector.reserve(n_hits);
186 
187  float kinetic_energy = 0, track_length = track.Length();
188  if (IsInvertedTrack(hpm)) {
189  for (auto it_hpm = hpm.begin(); it_hpm != hpm.end(); ++it_hpm) {
190  dEdxVector.push_back(it_hpm->dEdx);
191  dQdxVector.push_back(it_hpm->dQdx);
192  resRangeVector.push_back(it_hpm->path_fraction * track_length);
193  pitchVector.push_back(it_hpm->pitch);
194  XYZVector.push_back(it_hpm->xyz);
195  kinetic_energy += dEdxVector.back() * pitchVector.back();
196  }
197  }
198  else {
199  for (auto it_hpm = hpm.rbegin(); it_hpm != hpm.rend(); ++it_hpm) {
200  dEdxVector.push_back(it_hpm->dEdx);
201  dQdxVector.push_back(it_hpm->dQdx);
202  resRangeVector.push_back((1 - it_hpm->path_fraction) * track_length);
203  pitchVector.push_back(it_hpm->pitch);
204  XYZVector.push_back(it_hpm->xyz);
205  kinetic_energy += dEdxVector.back() * pitchVector.back();
206  }
207  }
208 
209  caloVector.emplace_back(kinetic_energy,
210  dEdxVector,
211  dQdxVector,
212  resRangeVector,
213  deadWireVector,
214  track_length,
215  pitchVector,
217  planeID);
218  assnTrackCaloVector.emplace_back(i_track);
219 }
220 
222 {
223 
224  for (auto const& hit : hpm)
225  hit.Print();
226 
227  std::cout << "Inverted? " << IsInvertedTrack(hpm) << std::endl;
228 }
intermediate_table::iterator iterator
geo::WireReadoutGeom const & wireReadoutGeom
void AnalyzeHit(detinfo::DetectorClocksData const &, detinfo::DetectorPropertiesData const &, recob::Hit const &, recob::Track const &, std::vector< std::pair< geo::WireID, float >> const &, std::vector< float > const &, HitPropertiesMultiset_t &, geo::WireReadoutGeom const &)
WireID NearestWireID(Point_t const &pos) const
Returns the ID of wire closest to the specified position.
Definition: PlaneGeo.cxx:485
bool IsInvertedTrack(HitPropertiesMultiset_t const &)
Declaration of signal hit object.
Point_t const & LocationAtPoint(size_t i) const
Access to track position at different points.
Definition: Track.h:160
void MakeCalorimetryObject(HitPropertiesMultiset_t const &hpm, recob::Track const &track, size_t const &i_track, std::vector< anab::Calorimetry > &caloVector, std::vector< size_t > &assnTrackCaloVector, geo::PlaneID const &planeID)
The data type to uniquely identify a Plane.
Definition: geo_types.h:364
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
Definition: Track.h:136
bool operator()(std::pair< geo::WireID, float > const &i, std::pair< geo::WireID, float > const &j)
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
Definition: Hit.h:254
geo::WireID const & WireID() const
Initial tdc tick for hit.
Definition: Hit.h:290
std::multiset< HitProperties, HitPropertySorter > HitPropertiesMultiset_t
dist_projected(recob::Hit const &h, geo::WireReadoutGeom const &wireReadoutGeom)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:289
std::vector< float > CreatePathLengthFractionVector(recob::Track const &track)
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
Definition: counter.h:292
double Length(size_t p=0) const
Access to various track properties.
Definition: Track.h:207
Interface for a class providing readout channel mapping to geometry.
parameter set interface
void PrintHitPropertiesMultiset(HitPropertiesMultiset_t const &hpm)
T get(std::string const &key) const
Definition: ParameterSet.h:314
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
Definition: electronics.h:73
double ConvertXToTicks(double X, int p, int t, int c) const
std::vector< Point_t > convertCollToPoint(std::vector< Point > const &coll)
Definition: TrackingTypes.h:68
Definition of data types for geometry description.
Detector simulation of raw signals on wires.
unsigned int Nplanes(TPCID const &tpcid=details::tpc_zero) const
Returns the total number of planes in the specified TPC.
void ExtractCalorimetry(detinfo::DetectorClocksData const &clock_data, detinfo::DetectorPropertiesData const &det_prop, std::vector< recob::Track > const &, std::vector< recob::Hit > const &, std::vector< std::vector< size_t >> const &, std::vector< anab::Calorimetry > &, std::vector< size_t > &, geo::WireReadoutGeom const &)
decltype(auto) get(T &&obj)
ADL-aware version of std::to_string.
Definition: StdUtils.h:120
TrackCalorimetryAlg(fhicl::ParameterSet const &p)
Contains all timing reference information for the detector.
Provides recob::Track data product.
double TrackPitchInView(recob::Track const &track, geo::View_t view, size_t trajectory_point=0U)
Returns the projected length of track on a wire pitch step [cm].
Definition: TrackUtils.cxx:76
double dEdx_AREA(detinfo::DetectorClocksData const &clock_data, detinfo::DetectorPropertiesData const &det_prop, recob::Hit const &hit, double pitch, double T0=0) const
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:46
recob::Hit const & hit
PlaneGeo const & Plane(TPCID const &tpcid, View_t view) const
Returns the specified wire.
Float_t track
Definition: plot.C:35
Utility functions to extract information from recob::Track
Interface to geometry for wire readouts .
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
constexpr PlaneID const & asPlaneID() const
Conversion to WireID (for convenience of notation).
Definition: geo_types.h:466