TrackCalorimetryAlg.cxx
Go to the documentation of this file.
1 /*!
2  * Title: Track Calorimetry Algorithim Class
3  * Author: Wes Ketchum (wketchum@lanl.gov), based on code in the Calorimetry_module
4  *
5  * Description: Algorithm that produces a calorimetry object given a track
6  * Input: recob::Track, Assn<recob::Spacepoint,recob::Track>, Assn<recob::Hit,recob::Track>
7  * Output: anab::Calorimetry, (and Assn<anab::Calorimetry,recob::Track>)
8 */
9 
10 #include "TrackCalorimetryAlg.h"
11 #include "fhiclcpp/ParameterSet.h"
12 
14 #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 
28 void
30  detinfo::DetectorClocksData const& clock_data,
31  detinfo::DetectorPropertiesData const& det_prop,
32  std::vector<recob::Track> const& trackVector,
33  std::vector<recob::Hit> const& hitVector,
34  std::vector<std::vector<size_t>> const& hit_indices_per_track,
35  std::vector<anab::Calorimetry>& caloVector,
36  std::vector<size_t>& assnTrackCaloVector,
37  Providers_t providers)
38 {
39  auto const& geom = *providers.get<geo::GeometryCore>();
40 
41  //loop over the track list
42  for (size_t i_track = 0; i_track < trackVector.size(); i_track++) {
43 
44  recob::Track const& track = trackVector[i_track];
45  std::vector<float> path_length_fraction_vec(CreatePathLengthFractionVector(track));
46 
47  //sort hits into each plane
48  std::vector<std::vector<size_t>> hit_indices_per_plane(geom.Nplanes());
49  for (auto const& i_hit : hit_indices_per_track[i_track])
50  hit_indices_per_plane[hitVector[i_hit].WireID().Plane].push_back(i_hit);
51 
52  //loop over the planes
53  for (size_t i_plane = 0; i_plane < geom.Nplanes(); i_plane++) {
54 
56  ReserveInternalVectors(hit_indices_per_plane[i_plane].size());
57 
58  //project down the track into wire/tick space for this plane
59  std::vector<std::pair<geo::WireID, float>> traj_points_in_plane(
60  track.NumberTrajectoryPoints());
61  for (size_t i_trjpt = 0; i_trjpt < track.NumberTrajectoryPoints(); i_trjpt++) {
62  double x_pos = track.LocationAtPoint(i_trjpt).X();
63  float tick = det_prop.ConvertXToTicks(x_pos, (int)i_plane, 0, 0);
64  traj_points_in_plane[i_trjpt] =
65  std::make_pair(geom.NearestWireID(track.LocationAtPoint(i_trjpt), i_plane), tick);
66  }
67 
68  HitPropertiesMultiset_t HitPropertiesMultiset;
69  //now loop through hits
70  for (auto const& i_hit : hit_indices_per_plane[i_plane])
71  AnalyzeHit(clock_data,
72  det_prop,
73  hitVector[i_hit],
74  track,
75  traj_points_in_plane,
76  path_length_fraction_vec,
77  HitPropertiesMultiset,
78  geom);
79 
80  //PrintHitPropertiesMultiset(HitPropertiesMultiset);
81  geo::PlaneID planeID(0, 0, i_plane);
83  HitPropertiesMultiset, track, i_track, caloVector, assnTrackCaloVector, planeID);
84 
85  } //end loop over planes
86 
87  } //end loop over tracks
88 
89 } //end ExtractCalorimetry
90 
92 public:
93  dist_projected(recob::Hit const& h, geo::GeometryCore const& g) : hit(h), geom(g) {}
94  bool
95  operator()(std::pair<geo::WireID, float> i, std::pair<geo::WireID, float> j)
96  {
97  float dw_i = ((int)(i.first.Wire) - (int)(hit.WireID().Wire)) * geom.WirePitch(i.first.Plane);
98  float dw_j = ((int)(j.first.Wire) - (int)(hit.WireID().Wire)) * geom.WirePitch(j.first.Plane);
99  float dt_i = i.second - hit.PeakTime();
100  float dt_j = j.second - hit.PeakTime();
101  return std::hypot(dw_i, dt_i) < std::hypot(dw_j, dt_j);
102  }
103 
104 private:
105  recob::Hit const& hit;
107 };
108 
109 std::vector<float>
111 {
112 
113  std::vector<float> trk_path_length_frac_vec(track.NumberTrajectoryPoints());
114 
115  float cumulative_path_length = 0;
116  const float total_path_length = track.Length();
117  for (size_t i_trj = 1; i_trj < track.NumberTrajectoryPoints(); i_trj++) {
118  cumulative_path_length += (track.LocationAtPoint(i_trj) - track.LocationAtPoint(i_trj - 1)).R();
119  trk_path_length_frac_vec[i_trj] = cumulative_path_length / total_path_length;
120  }
121 
122  return trk_path_length_frac_vec;
123 }
124 
125 void
127  detinfo::DetectorClocksData const& clock_data,
128  detinfo::DetectorPropertiesData const& det_prop,
129  recob::Hit const& hit,
130  recob::Track const& track,
131  std::vector<std::pair<geo::WireID, float>> const& traj_points_in_plane,
132  std::vector<float> const& path_length_fraction_vec,
133  HitPropertiesMultiset_t& HitPropertiesMultiset,
134  geo::GeometryCore const& geom)
135 {
136 
137  size_t traj_iter = std::distance(traj_points_in_plane.begin(),
138  std::min_element(traj_points_in_plane.begin(),
139  traj_points_in_plane.end(),
140  dist_projected(hit, geom)));
141  float pitch = lar::util::TrackPitchInView(track, geom.View(hit.WireID().Plane), traj_iter);
142 
143  HitPropertiesMultiset.emplace(hit.Integral(),
144  hit.Integral() / pitch,
145  caloAlg.dEdx_AREA(clock_data, det_prop, hit, pitch),
146  pitch,
147  track.LocationAtPoint<TVector3>(traj_iter),
148  path_length_fraction_vec[traj_iter]);
149 }
150 
151 bool
153 {
154 
155  if (hpm.size() <= fNHitsToDetermineStart) return false;
156 
157  float charge_start = 0, charge_end = 0;
158  unsigned int counter = 0;
159  for (HitPropertiesMultiset_t::iterator it_hpm = hpm.begin(); it_hpm != hpm.end(); it_hpm++) {
160  charge_start += (*it_hpm).charge;
161  counter++;
162  if (counter == fNHitsToDetermineStart) break;
163  }
164 
165  counter = 0;
166  for (HitPropertiesMultiset_t::reverse_iterator it_hpm = hpm.rbegin(); it_hpm != hpm.rend();
167  it_hpm++) {
168  charge_end += (*it_hpm).charge;
169  counter++;
170  if (counter == fNHitsToDetermineStart) break;
171  }
172 
173  return (charge_start > charge_end);
174 }
175 
176 void
178  recob::Track const& track,
179  size_t const& i_track,
180  std::vector<anab::Calorimetry>& caloVector,
181  std::vector<size_t>& assnTrackCaloVector,
182  geo::PlaneID const& planeID)
183 {
184  size_t n_hits = hpm.size();
185  std::vector<float> dEdxVector, dQdxVector, resRangeVector, deadWireVector, pitchVector;
186  std::vector<TVector3> XYZVector;
187 
188  dEdxVector.reserve(n_hits);
189  dQdxVector.reserve(n_hits);
190  resRangeVector.reserve(n_hits);
191  deadWireVector.reserve(n_hits);
192  pitchVector.reserve(n_hits);
193  XYZVector.reserve(n_hits);
194 
195  float kinetic_energy = 0, track_length = track.Length();
196  if (IsInvertedTrack(hpm)) {
197 
198  for (HitPropertiesMultiset_t::iterator it_hpm = hpm.begin(); it_hpm != hpm.end(); it_hpm++) {
199  dEdxVector.push_back((*it_hpm).dEdx);
200  dQdxVector.push_back((*it_hpm).dQdx);
201  resRangeVector.push_back((*it_hpm).path_fraction * track_length);
202  pitchVector.push_back((*it_hpm).pitch);
203  XYZVector.push_back((*it_hpm).xyz);
204  kinetic_energy += dEdxVector.back() * pitchVector.back();
205  }
206  }
207  else {
208 
209  for (HitPropertiesMultiset_t::reverse_iterator it_hpm = hpm.rbegin(); it_hpm != hpm.rend();
210  it_hpm++) {
211  dEdxVector.push_back((*it_hpm).dEdx);
212  dQdxVector.push_back((*it_hpm).dQdx);
213  resRangeVector.push_back((1 - (*it_hpm).path_fraction) * track_length);
214  pitchVector.push_back((*it_hpm).pitch);
215  XYZVector.push_back((*it_hpm).xyz);
216  kinetic_energy += dEdxVector.back() * pitchVector.back();
217  }
218  }
219 
220  caloVector.emplace_back(kinetic_energy,
221  dEdxVector,
222  dQdxVector,
223  resRangeVector,
224  deadWireVector,
225  track_length,
226  pitchVector,
228  planeID);
229  assnTrackCaloVector.emplace_back(i_track);
230 }
231 
232 void
234 {
235 
236  for (auto const& hit : hpm)
237  hit.Print();
238 
239  std::cout << "Inverted? " << IsInvertedTrack(hpm) << std::endl;
240 }
intermediate_table::iterator iterator
geo::GeometryCore const & geom
static constexpr double g
Definition: Units.h:144
geo::WireID WireID() const
Definition: Hit.h:233
bool IsInvertedTrack(HitPropertiesMultiset_t const &)
Point_t const & LocationAtPoint(size_t i) const
Definition: Track.h:126
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)
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 > &, Providers_t providers)
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
struct vector vector
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
Definition: Track.h:102
Provider const * get() const
Returns the provider with the specified type.
Definition: ProviderPack.h:193
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
Definition: Hit.h:224
std::multiset< HitProperties, HitPropertySorter > HitPropertiesMultiset_t
dist_projected(recob::Hit const &h, geo::GeometryCore const &g)
std::enable_if_t< std::is_arithmetic_v< T >, T > hypot(T x, T y)
Definition: hypot.h:60
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
std::vector< float > CreatePathLengthFractionVector(recob::Track const &track)
double Length(size_t p=0) const
Access to various track properties.
Definition: Track.h:167
bool operator()(std::pair< geo::WireID, float > i, std::pair< geo::WireID, float > j)
void PrintHitPropertiesMultiset(HitPropertiesMultiset_t const &hpm)
T get(std::string const &key) const
Definition: ParameterSet.h:271
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
Definition: electronics.h:75
p
Definition: test.py:223
double ConvertXToTicks(double X, int p, int t, int c) const
void ReserveInternalVectors(size_t s)
std::vector< Point_t > convertCollToPoint(std::vector< Point > const &coll)
Definition: TrackingTypes.h:55
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:493
Description of geometry of one entire detector.
View_t View(geo::PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
Definition of data types for geometry description.
Detector simulation of raw signals on wires.
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::GeometryCore const &)
Declaration of signal hit object.
TrackCalorimetryAlg(fhicl::ParameterSet const &p)
Contains all timing reference information for the detector.
Container for a list of pointers to providers.
Definition: ProviderPack.h:114
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:78
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
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:48
recob::Hit const & hit
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
Utility functions to extract information from recob::Track
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
QTextStream & endl(QTextStream &s)