All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GnocchiCalorimetry_module.cc
Go to the documentation of this file.
1 // A gnew Calorimetry module
2 //
3 // Re-write of the Calorimetry module ported into art by E. Chruch
4 // from the original (ArgoNeuT) calorimetry module by Ornella Palamara and Maddalena Antonello.
5 //
6 // Gray Putnam
7 // grayputnam@uchicago.edu
8 
9 #include <string>
10 #include <optional>
11 #include <cmath>
12 #include <limits> // std::numeric_limits<>
13 #include <numeric> // std::accumulate
14 
19 
28 #include "lardata/ArtDataHelper/TrackUtils.h" // lar::util::TrackPitchInView()
31 #include "larcorealg/CoreUtils/NumericUtils.h" // util::absDiff()
32 
35 
36 // ROOT includes
37 #include <TMath.h>
38 #include <TGraph.h>
39 #include <TF1.h>
40 
41 #include "art/Framework/Core/EDProducer.h"
42 #include "art/Framework/Core/ModuleMacros.h"
43 #include "canvas/Persistency/Common/FindManyP.h"
44 #include "art/Framework/Principal/Event.h"
45 #include "fhiclcpp/ParameterSet.h"
46 #include "fhiclcpp/types/DelegatedParameter.h"
47 #include "art/Framework/Principal/Handle.h"
48 #include "art/Utilities/make_tool.h"
49 #include "canvas/Persistency/Common/Ptr.h"
50 #include "art/Framework/Services/Registry/ServiceHandle.h"
51 #include "messagefacility/MessageLogger/MessageLogger.h"
52 #include "cetlib/pow.h" // cet::sum_of_squares()
53 
54 namespace {
55  constexpr unsigned int int_max_as_unsigned_int{std::numeric_limits<int>::max()};
56 }
57 
58 namespace calo {
59 
60 class GnocchiCalorimetry: public art::EDProducer {
61  public:
62  struct Config {
63  using Comment = fhicl::Comment;
64  using Name = fhicl::Name;
65 
66  enum ChargeMethod: unsigned {
70  };
71 
72 
73  fhicl::Atom<std::string> TrackModuleLabel {
74  Name("TrackModuleLabel"),
75  Comment("Module label for track producer.")
76  };
77 
78  fhicl::Atom<std::string> T0ModuleLabel {
79  Name("T0ModuleLabel"),
80  Comment("Module label for T0 time producer."),
81  ""
82  };
83 
84  fhicl::Atom<std::string> AssocHitModuleLabel {
85  Name("AssocHitModuleLabel"),
86  Comment("Module label for association between tracks and hits. If not set, defaults to TrackModuleLabel."),
87  ""
88  };
89 
90  fhicl::Atom<unsigned> ChargeMethod {
91  Name("ChargeMethod"),
92  Comment("Method used to extract charge from a hit. Options: 0==Amplitude(), 1==Integral(), 2==SummedADC(). See the ChargeMethod enum.")
93  };
94 
95  fhicl::Atom<bool> FieldDistortion {
96  Name("FieldDistortion"),
97  Comment("True if field distortion (i.e. from space charge) is included in the input.")
98  };
99 
100  fhicl::Atom<bool> FieldDistortionEfield {
101  Name("FieldDistortionEfield"),
102  Comment("True if field distortion (i.e. from space charge) is included in the input.")
103  };
104 
106  Name("TrackIsFieldDistortionCorrected"),
107  Comment("Whether the space-points on the input tracks have their points corrected for the field distortions. "
108  "I.e. whether the track trajectory points represent charge as seen by wires or the 3D particle trajectory.")
109  };
110 
111  fhicl::Atom<unsigned> Cryostat {
112  Name("Cryostat"),
113  Comment("Which cryostat number the input tracks occupy.")
114  };
115 
116  fhicl::Atom<float> FieldDistortionCorrectionXSign {
117  Name("FieldDistortionCorrectionXSign"),
118  Comment("Sign of the field distortion correction to be applied in the X direction. Positive by default."),
119  1.
120  };
121 
122  fhicl::Table<calo::CalorimetryAlg::Config> CalorimetryAlgConfig {
123  Name("CaloAlg"),
124  Comment("Configuration for the calo::CalorimetryAlg")
125  };
126 
127  fhicl::DelegatedParameter NormTools {
128  Name("NormTools"),
129  Comment("List of INormalizeCharge tool configurations to use.")
130  };
131 
132  };
133 
134  using Parameters = art::EDProducer::Table<Config>;
135 
136  explicit GnocchiCalorimetry(Parameters const& config);
137 
138  void produce(art::Event& evt) override;
139 
140 
141  private:
144  std::vector<std::unique_ptr<INormalizeCharge>> fNormTools;
145 
146  // helper functions
147  std::vector<std::vector<unsigned>> OrganizeHits(const std::vector<art::Ptr<recob::Hit>> &hits,
148  const std::vector<const recob::TrackHitMeta *> &thms,
149  const recob::Track &track, unsigned nplanes);
150  std::vector<std::vector<unsigned>> OrganizeHitsIndividual(const std::vector<art::Ptr<recob::Hit>> &hits,
151  const std::vector<const recob::TrackHitMeta *> &thms,
152  const recob::Track &track, unsigned nplanes);
153  std::vector<std::vector<unsigned>> OrganizeHitsSnippets(const std::vector<art::Ptr<recob::Hit>> &hits,
154  const std::vector<const recob::TrackHitMeta *> &thms,
155  const recob::Track &track, unsigned nplanes);
156  bool HitIsValid(const art::Ptr<recob::Hit> hit, const recob::TrackHitMeta *thm, const recob::Track &track);
157  geo::Point_t GetLocation(const recob::Track &track, const art::Ptr<recob::Hit> hit, const recob::TrackHitMeta *meta);
158  geo::Point_t GetLocationAtWires(const recob::Track &track, const art::Ptr<recob::Hit> hit, const recob::TrackHitMeta *meta);
161  double GetPitch(const recob::Track &track, const art::Ptr<recob::Hit> hit, const recob::TrackHitMeta *meta);
162  double GetCharge(const art::Ptr<recob::Hit> hit);
163  double GetEfield(const detinfo::DetectorPropertiesData &dprop, const recob::Track &track, const art::Ptr<recob::Hit> hit, const recob::TrackHitMeta *meta);
164  double Normalize(double dQdx, const art::Event &e, const recob::Hit &h, const geo::Point_t &location, const geo::Vector_t &direction, double t0);
165 };
166 
167 } // end namespace calo
168 
169 
171  EDProducer{param},
172  fConfig(param()),
173  fCaloAlg(fConfig.CalorimetryAlgConfig())
174 {
175  produces< std::vector<anab::Calorimetry> >();
176  produces< art::Assns<recob::Track, anab::Calorimetry> >();
177 
178  std::vector<fhicl::ParameterSet> norm_tool_configs = fConfig.NormTools.get<std::vector<fhicl::ParameterSet>>();
179  for (const fhicl::ParameterSet &p: norm_tool_configs) {
180  fNormTools.push_back(art::make_tool<INormalizeCharge>(p));
181  }
182 
183 }
184 
186  // Get services
187  art::ServiceHandle<geo::Geometry const> geom;
188  auto const clock_data = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
189  auto const det_prop =
190  art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt, clock_data);
191 
192  size_t nplanes = geom->Nplanes();
193 
194  // Define output collections
195  std::unique_ptr< std::vector<anab::Calorimetry> > outputCalo(new std::vector<anab::Calorimetry>);
196  std::unique_ptr< art::Assns<recob::Track, anab::Calorimetry> > outputCaloAssn(new art::Assns<recob::Track, anab::Calorimetry>);
197 
198  // collect input
199  art::Handle< std::vector<recob::Track> > trackListHandle;
200  std::vector<art::Ptr<recob::Track> > tracklist;
201  if (evt.getByLabel(fConfig.TrackModuleLabel(), trackListHandle)) {
202  art::fill_ptr_vector(tracklist, trackListHandle);
203  }
204 
205  // get the label to collect this hits
206  const std::string &hitLabel = (fConfig.AssocHitModuleLabel() == "") ? fConfig.TrackModuleLabel() : fConfig.AssocHitModuleLabel();
207  art::FindManyP<recob::Hit, recob::TrackHitMeta> fmHits(trackListHandle, evt, hitLabel);
208 
209  // must be valid if the T0 module label is non-empty
210  art::FindManyP<anab::T0> fmT0s(trackListHandle, evt, fConfig.T0ModuleLabel());
211 
212  // iterate over all the tracks
213  for (unsigned trk_i = 0; trk_i < tracklist.size(); trk_i++) {
214  const recob::Track &track = *tracklist[trk_i];
215 
216  // collect input for this track
217  const std::vector<art::Ptr<recob::Hit>> &hits = fmHits.at(trk_i);
218  const std::vector<const recob::TrackHitMeta *> &thms = fmHits.data(trk_i);
219 
220  double T0 = 0;
221  if (fConfig.T0ModuleLabel().size()) {
222  const std::vector<art::Ptr<anab::T0>> &this_t0s = fmT0s.at(trk_i);
223  if (this_t0s.size()) T0 = this_t0s.at(0)->Time();
224  }
225 
226  // organize the hits by plane
227  std::vector<std::vector<unsigned>> hit_indices = OrganizeHits(hits, thms, track, nplanes);
228 
229  for (unsigned plane_i = 0; plane_i < nplanes; plane_i++) {
230 
231  float kinetic_energy = 0.;
232  std::vector<float> dEdxs;
233  std::vector<float> dQdxs;
234  std::vector<float> resranges;
235  std::vector<float> deadwireresranges;
236  float range = 0.;
237  std::vector<float> pitches;
238  std::vector<geo::Point_t> xyzs;
239  std::vector<size_t> tp_indices;
240  geo::PlaneID plane;
241 
242  // setup the plane ID
243  plane.Plane = plane_i;
244  plane.TPC = 0; // arbitrary -- tracks can cross TPC boundaries
245  plane.Cryostat = fConfig.Cryostat();
246  plane.isValid = true;
247 
248  std::vector<float> lengths;
249  for (unsigned hit_i = 0; hit_i < hit_indices[plane_i].size(); hit_i++) {
250  unsigned hit_index = hit_indices[plane_i][hit_i];
251 
252  // Get the location of this point
253  geo::Point_t location = GetLocation(track, hits[hit_index], thms[hit_index]);
254 
255  // Get the pitch
256  double pitch = GetPitch(track, hits[hit_index], thms[hit_index]);
257 
258  // And the charge
259  double charge = GetCharge(hits[hit_index]);
260 
261  // Get the EField
262  double EField = GetEfield(det_prop, track, hits[hit_index], thms[hit_index]);
263 
264  double dQdx = charge / pitch;
265 
266  // Normalize out the detector response
267  dQdx = Normalize(dQdx, evt,
268  *hits[hit_index], track.LocationAtPoint(thms[hit_index]->Index()), track.DirectionAtPoint(thms[hit_index]->Index()), T0);
269 
270  // turn into dEdx
271  double dEdx = (fConfig.ChargeMethod() == calo::GnocchiCalorimetry::Config::cmAmplitude) ? \
272  fCaloAlg.dEdx_AMP(clock_data, det_prop, dQdx, hits[hit_index]->PeakTime(), hits[hit_index]->WireID().Plane, T0, EField) : \
273  fCaloAlg.dEdx_AREA(clock_data, det_prop, dQdx, hits[hit_index]->PeakTime(), hits[hit_index]->WireID().Plane, T0, EField);
274 
275  // save the length between each pair of hits
276  if (xyzs.size() == 0) {
277  lengths.push_back(0.);
278  }
279  else {
280  lengths.push_back((location - xyzs.back()).r());
281  }
282 
283  // save stuff
284  dEdxs.push_back(dEdx);
285  dQdxs.push_back(dQdx);
286  pitches.push_back(pitch);
287  xyzs.push_back(location);
288  kinetic_energy += dEdx * pitch;
289 
290  // TODO: FIXME
291  // It seems weird that the "trajectory-point-index" actually is the
292  // index of the hit... is this a bug in the documentation
293  // of anab::Calorimetry?
294  //
295  // i.e. -- I think this piece of code should actually be:
296  // tp_indices.push_back(thms[hit_index]->Index());
297  tp_indices.push_back(hits[hit_index].key());
298 
299 
300  } // end iterate over hits
301 
302 
303  // turn the lengths vector into a residual-range vector and total length
304  if (lengths.size() > 1) {
305  range = std::accumulate(lengths.begin(), lengths.end(), 0.);
306 
307  // check the direction that the hits are going in the track:
308  // upstream (end-start) or downstream (start-end)
309  bool is_downstream = \
310  (track.Trajectory().Start() - xyzs[0]).r() + (track.Trajectory().End() - xyzs.back()).r() <
311  (track.Trajectory().End() - xyzs[0]).r() + (track.Trajectory().Start() - xyzs.back()).r();
312 
313  resranges.resize(lengths.size());
314  if (is_downstream) {
315  resranges[lengths.size() - 1] = lengths.back() / 2.;
316  for (int i_len = lengths.size() - 2; i_len >= 0; i_len --) {
317  resranges[i_len] = resranges[i_len+1] + lengths[i_len+1];
318  }
319  }
320  else {
321  resranges[0] = lengths[1] / 2.;
322  for (unsigned i_len = 1; i_len < lengths.size(); i_len ++) {
323  resranges[i_len] = resranges[i_len-1] + lengths[i_len];
324  }
325  }
326  }
327 
328  // save the Calorimetry output
329  //
330  // Bogus if less than two hits on this plane
331  if (lengths.size() > 1) {
332  outputCalo->push_back(anab::Calorimetry(kinetic_energy,
333  dEdxs,
334  dQdxs,
335  resranges,
336  deadwireresranges,
337  range,
338  pitches,
339  xyzs,
340  tp_indices,
341  plane));
342  }
343  else {
344  outputCalo->push_back(anab::Calorimetry(util::kBogusD,
345  {},
346  {},
347  {},
348  {},
350  {},
351  {},
352  {},
353  plane));
354  }
355 
356  util::CreateAssn(*this, evt, *outputCalo, tracklist[trk_i], *outputCaloAssn);
357 
358  } // end iterate over planes
359 
360  } // end iterate over tracks
361 
362  evt.put(std::move(outputCalo));
363  evt.put(std::move(outputCaloAssn));
364 
365  return;
366 
367 }
368 
369 std::vector<std::vector<unsigned>> calo::GnocchiCalorimetry::OrganizeHits(const std::vector<art::Ptr<recob::Hit>> &hits,
370  const std::vector<const recob::TrackHitMeta *> &thms,
371  const recob::Track &track, unsigned nplanes) {
372  // charge is computed per hit -- we organize hits indivudally
373  if (fConfig.ChargeMethod() == calo::GnocchiCalorimetry::Config::cmIntegral || fConfig.ChargeMethod() == calo::GnocchiCalorimetry::Config::cmAmplitude) {
374  return OrganizeHitsIndividual(hits, thms, track, nplanes);
375  }
376  // charge is computed per snippet -- we organize hits by snippet
377  else {
378  return OrganizeHitsSnippets(hits, thms, track, nplanes);
379  }
380 }
381 
382 std::vector<std::vector<unsigned>> calo::GnocchiCalorimetry::OrganizeHitsIndividual(const std::vector<art::Ptr<recob::Hit>> &hits,
383  const std::vector<const recob::TrackHitMeta *> &thms,
384  const recob::Track &track, unsigned nplanes) {
385  std::vector<std::vector<unsigned>> ret(nplanes);
386  for (unsigned i = 0; i < hits.size(); i++) {
387  if (HitIsValid(hits[i], thms[i], track)) {
388  ret[hits[i]->WireID().Plane].push_back(i);
389  }
390  }
391 
392  return ret;
393 }
394 
395 std::vector<std::vector<unsigned>> calo::GnocchiCalorimetry::OrganizeHitsSnippets(const std::vector<art::Ptr<recob::Hit>> &hits,
396  const std::vector<const recob::TrackHitMeta *> &thms,
397  const recob::Track &track, unsigned nplanes) {
398  // In this case, we need to only accept one hit in each snippet
399  // Snippets are counted by the Start, End, and Wire. If all these are the same for a hit, then they are on the same snippet.
400  //
401  // If there are multiple valid hits on the same snippet, we need a way to pick the best one.
402  // (TODO: find a good way). The current method is to take the one with the highest charge integral.
403  struct HitIdentifier {
404  int startTick;
405  int endTick;
406  int wire;
407  float integral;
408 
409  // construct
410  explicit HitIdentifier(const recob::Hit &hit):
411  startTick(hit.StartTick()),
412  endTick(hit.EndTick()),
413  wire(hit.WireID().Wire),
414  integral(hit.Integral())
415  {}
416 
417  // Defines whether two hits are on the same snippet
418  inline bool operator==(const HitIdentifier& rhs) const {
419  return startTick == rhs.startTick && endTick == rhs.endTick && wire == rhs.wire;
420  }
421 
422  // Defines which hit to pick between two both on the same snippet
423  inline bool operator>(const HitIdentifier& rhs) const {
424  return integral > rhs.integral;
425  }
426  };
427 
428  std::vector<std::vector<unsigned>> ret(nplanes);
429  std::vector<std::vector<HitIdentifier>> hit_idents(nplanes);
430  for (unsigned i = 0; i < hits.size(); i++) {
431  if (HitIsValid(hits[i], thms[i], track)) {
432  HitIdentifier this_ident(*hits[i]);
433 
434  // check if we have found a hit on this snippet before
435  bool found_snippet = false;
436  for (unsigned j = 0; j < ret[hits[i]->WireID().Plane].size(); j++) {
437  if (this_ident == hit_idents[hits[i]->WireID().Plane][j]) {
438  found_snippet = true;
439  if (this_ident > hit_idents[hits[i]->WireID().Plane][j]) {
440  ret[hits[i]->WireID().Plane][j] = i;
441  hit_idents[hits[i]->WireID().Plane][j] = this_ident;
442  }
443  break;
444  }
445  }
446  if (!found_snippet) {
447  ret[hits[i]->WireID().Plane].push_back(i);
448  hit_idents[hits[i]->WireID().Plane].push_back(this_ident);
449  }
450  }
451  }
452  return ret;
453 }
454 
455 bool calo::GnocchiCalorimetry::HitIsValid(const art::Ptr<recob::Hit> hit, const recob::TrackHitMeta *thm, const recob::Track &track) {
456  if (thm->Index() == int_max_as_unsigned_int) return false;
457  if (!track.HasValidPoint(thm->Index())) return false;
458  return true;
459 }
460 
462  geo::Point_t loc = track.LocationAtPoint(meta->Index());
463  return !fConfig.TrackIsFieldDistortionCorrected() ? WireToTrajectoryPosition(loc, hit->WireID()) : loc;
464 }
465 
467  auto const* sce = lar::providerFrom<spacecharge::SpaceChargeService>();
468 
469  geo::Point_t ret = loc;
470 
471  if (sce->EnableCalSpatialSCE() && fConfig.FieldDistortion()) {
472  geo::Vector_t offset = sce->GetCalPosOffsets(ret, tpc.TPC);
473 
474  ret.SetX(ret.X() + fConfig.FieldDistortionCorrectionXSign() * offset.X());
475  ret.SetY(ret.Y() + offset.Y());
476  ret.SetZ(ret.Z() + offset.Z());
477  }
478 
479  return ret;
480 
481 }
482 
484  geo::Point_t loc = track.LocationAtPoint(meta->Index());
485  return fConfig.TrackIsFieldDistortionCorrected() ? TrajectoryToWirePosition(loc, hit->WireID()) : loc;
486 }
487 
489  auto const* sce = lar::providerFrom<spacecharge::SpaceChargeService>();
490  art::ServiceHandle<geo::Geometry const> geom;
491 
492  geo::Point_t ret = loc;
493 
494  if (sce->EnableCalSpatialSCE() && fConfig.FieldDistortion()) {
495  // Returned X is the drift -- multiply by the drift direction to undo this
496  int corr = geom->TPC(tpc.TPC).DriftDir()[0];
497 
498  geo::Vector_t offset = sce->GetPosOffsets(ret);
499 
500  ret.SetX(ret.X() + corr * fConfig.FieldDistortionCorrectionXSign() * offset.X());
501  ret.SetY(ret.Y() + offset.Y());
502  ret.SetZ(ret.Z() + offset.Z());
503  }
504 
505  return ret;
506 }
507 
508 double calo::GnocchiCalorimetry::GetPitch(const recob::Track &track, const art::Ptr<recob::Hit> hit, const recob::TrackHitMeta *meta) {
509  art::ServiceHandle<geo::Geometry const> geom;
510  auto const* sce = lar::providerFrom<spacecharge::SpaceChargeService>();
511 
512  double angleToVert = geom->WireAngleToVertical(hit->View(), hit->WireID().TPC, hit->WireID().Cryostat) - 0.5*::util::pi<>();
513 
515 
516  // "dir" should be the direction that the wires see. If the track already has the field
517  // distortion corrections applied, then we need to de-apply them to get the direction as
518  // seen by the wire planes
519  if (sce->EnableCalSpatialSCE() && fConfig.FieldDistortion() && fConfig.TrackIsFieldDistortionCorrected()) {
520  geo::Point_t loc = track.LocationAtPoint(meta->Index());
521 
522  // compute the dir of the track trajectory
523  geo::Vector_t track_dir = track.DirectionAtPoint(meta->Index());
524  geo::Point_t loc_mdx = loc - track_dir * (geom->WirePitch(hit->View()) / 2.);
525  geo::Point_t loc_pdx = loc + track_dir * (geom->WirePitch(hit->View()) / 2.);
526 
527  loc_mdx = TrajectoryToWirePosition(loc_mdx, hit->WireID());
528  loc_pdx = TrajectoryToWirePosition(loc_pdx, hit->WireID());
529 
530  // Direction at wires
531  dir = (loc_pdx - loc_mdx) / (loc_mdx - loc_pdx).r();
532  }
533  // If there is no space charge or the track is not yet corrected, then the dir
534  // is the track is what we want
535  else {
536  dir = track.DirectionAtPoint(meta->Index());
537  }
538 
539  double cosgamma = std::abs(std::sin(angleToVert)*dir.Y() + std::cos(angleToVert)*dir.Z());
540  double pitch;
541  if (cosgamma) {
542  pitch = geom->WirePitch(hit->View())/cosgamma;
543  }
544  else {
545  pitch = 0.;
546  }
547 
548  // now take the pitch computed on the wires and correct it back to the particle trajectory
549  geo::Point_t loc_w = GetLocationAtWires(track, hit, meta);
550 
551  geo::Point_t locw_pdx_traj = WireToTrajectoryPosition(loc_w + pitch*dir, hit->WireID());
552  geo::Point_t loc = WireToTrajectoryPosition(loc_w, hit->WireID());
553 
554  pitch = (locw_pdx_traj - loc).R();
555 
556  return pitch;
557 }
558 
559 double calo::GnocchiCalorimetry::GetCharge(const art::Ptr<recob::Hit> hit) {
560  switch (fConfig.ChargeMethod()) {
562  return hit->Integral();
564  return hit->PeakAmplitude();
566  return hit->SummedADC();
567  default:
568  return 0.;
569  }
570  return 0.;
571 }
572 
573 
574 double calo::GnocchiCalorimetry::Normalize(double dQdx, const art::Event &e, const recob::Hit &h, const geo::Point_t &location, const geo::Vector_t &direction, double t0) {
575  double ret = dQdx;
576  for (auto const &nt: fNormTools) {
577  ret = nt->Normalize(ret, e, h, location, direction, t0);
578  }
579 
580  return ret;
581 }
582 
583 double calo::GnocchiCalorimetry::GetEfield(const detinfo::DetectorPropertiesData &dprop, const recob::Track &track, const art::Ptr<recob::Hit> hit, const recob::TrackHitMeta *meta) {
584  auto const* sce = lar::providerFrom<spacecharge::SpaceChargeService>();
585 
586  double EField = dprop.Efield();
587  if (sce->EnableSimEfieldSCE() && fConfig.FieldDistortionEfield()) {
588  // Gets relative E field Distortions
589  geo::Vector_t EFieldOffsets = sce->GetEfieldOffsets(GetLocation(track, hit, meta));
590  // Add 1 in X direction as this is the direction of the drift field
591  EFieldOffsets = EFieldOffsets + geo::Vector_t{1, 0, 0};
592  // Convert to Absolute E Field from relative
593  EFieldOffsets = EField * EFieldOffsets;
594  // We only care about the magnitude for recombination
595  EField = EFieldOffsets.r();
596  }
597  return EField;
598 
599 }
600 
601 DEFINE_ART_MODULE(calo::GnocchiCalorimetry)
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
GnocchiCalorimetry(Parameters const &config)
Functions to help with numbers.
BEGIN_PROLOG TPC Trig offset(g4 rise time) ProjectToHeight
Definition: CORSIKAGen.fcl:7
void produce(art::Event &evt) override
geo::WireID WireID() const
Definition: Hit.h:233
const recob::TrackTrajectory & Trajectory() const
Access to the stored recob::TrackTrajectory.
Declaration of signal hit object.
art::EDProducer::Table< Config > Parameters
Point_t const & LocationAtPoint(size_t i) const
pdgs p
Definition: selectors.fcl:22
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
bool isValid
Whether this ID points to a valid element.
Definition: geo_types.h:211
bool HasValidPoint(size_t i) const
Class to keep data related to recob::Hit associated with recob::Track.
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:212
geo::Point_t GetLocation(const spacecharge::SpaceCharge *sce, geo::Point_t loc_w, geo::TPCID TPC, float xsign=1.)
Get the location in the presence of space charge.
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
Definition: Hit.h:224
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:580
bool HitIsValid(const art::Ptr< recob::Hit > hit, const recob::TrackHitMeta *thm, const recob::Track &track)
process_name use argoneut_mc_hitfinder track
Data related to recob::Hit associated with recob::Track.The purpose is to collect several variables t...
Definition: TrackHitMeta.h:43
process_name hit
Definition: cheaterreco.fcl:51
double Normalize(double dQdx, const art::Event &e, const recob::Hit &h, const geo::Point_t &location, const geo::Vector_t &direction, double t0)
std::vector< std::vector< unsigned > > OrganizeHitsSnippets(const std::vector< art::Ptr< recob::Hit >> &hits, const std::vector< const recob::TrackHitMeta * > &thms, const recob::Track &track, unsigned nplanes)
geo::Point_t GetLocationAtWires(const recob::Track &track, const art::Ptr< recob::Hit > hit, const recob::TrackHitMeta *meta)
geo::Point_t GetLocationAtWires(const spacecharge::SpaceCharge *sce, const geo::GeometryCore *geo, geo::Point_t loc, geo::TPCID TPC, float xsign=1.)
Get the SCE-distorted location (i.e. the location &quot;seen&quot; by the wireplanes)
double Efield(unsigned int planegap=0) const
kV/cm
fhicl::Atom< std::string > TrackModuleLabel
while getopts h
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
fhicl::Atom< std::string > T0ModuleLabel
T abs(T value)
geo::Point_t WireToTrajectoryPosition(const geo::Point_t &loc, const geo::TPCID &tpc)
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
std::vector< std::unique_ptr< INormalizeCharge > > fNormTools
double GetEfield(const detinfo::DetectorPropertiesData &dprop, const recob::Track &track, const art::Ptr< recob::Hit > hit, const recob::TrackHitMeta *meta)
geo::Point_t WireToTrajectoryPosition(const geo::Point_t &loc, const geo::TPCID &tpc)
BEGIN_PROLOG vertical distance to the surface Name
geo::Point_t TrajectoryToWirePosition(const geo::Point_t &loc, const geo::TPCID &tpc)
double GetPitch(const geo::GeometryCore *geo, const spacecharge::SpaceCharge *sce, geo::Point_t loc, geo::Vector_t dir, geo::View_t view, geo::TPCID tpc, bool correct_sce, bool track_is_sce_corrected, float xsign=1.)
Computes the track-pitch on a plane given an input direction and location.
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
raw::TDCtick_t StartTick() const
Initial tdc tick for hit.
Definition: Hit.h:216
float dEdx(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const TCSlice &slc, TP3D &tp3d)
Definition: PFPUtils.cxx:2687
Provides recob::Track data product.
tuple dir
Definition: dropbox.py:28
Encapsulate the geometry of a wire.
raw::TDCtick_t EndTick() const
Final tdc tick for hit.
Definition: Hit.h:217
fhicl::Table< calo::CalorimetryAlg::Config > CalorimetryAlgConfig
bool CreateAssn(art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t index=UINT_MAX)
Creates a single one-to-one association.
std::vector< std::vector< unsigned > > OrganizeHits(const std::vector< art::Ptr< recob::Hit >> &hits, const std::vector< const recob::TrackHitMeta * > &thms, const recob::Track &track, unsigned nplanes)
constexpr bool operator>(Interval< Q, Cat > const a, Quantity< Args...> const b) noexcept
Definition: intervals.h:476
Encapsulate the construction of a single detector plane.
Point_t const & End() const
Returns the position of the last valid point of the trajectory [cm].
Interface for experiment-specific channel quality info provider.
do i e
double GetPitch(const recob::Track &track, const art::Ptr< recob::Hit > hit, const recob::TrackHitMeta *meta)
geo::Point_t TrajectoryToWirePosition(const geo::Point_t &loc, const geo::TPCID &tpc)
unsigned int Index() const
Hit index along the track trajectory.
Definition: TrackHitMeta.h:55
double GetEfield(const detinfo::DetectorPropertiesData &dprop, const spacecharge::SpaceCharge *sce, geo::Point_t loc, geo::TPCID TPC, bool correct_loc_sce, float xsign=1.)
Get the E-Field in the presence of space charge.
Vector_t DirectionAtPoint(size_t i) const
double GetCharge(const art::Ptr< recob::Hit > hit)
constexpr double kBogusD
obviously bogus double value
geo::Point_t GetLocation(const recob::Track &track, const art::Ptr< recob::Hit > hit, const recob::TrackHitMeta *meta)
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:48
TCEvent evt
Definition: DataStructs.cxx:8
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:406
Interface for experiment-specific service for channel quality info.
Collection of Physical constants used in LArSoft.
fhicl::Atom< std::string > AssocHitModuleLabel
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
Point_t const & Start() const
Returns the position of the first valid point of the trajectory [cm].
esac echo uname r
Utility functions to extract information from recob::Track
bool operator==(infinite_endcount_iterator< T > const &, count_iterator< T > const &)
Definition: counter.h:269
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a &quot;fitted&quot; track:
process_name opdaq physics producers generator physics producers generator physics producers generator physics producers generator physics producers generator physics producers generator physics producers generator physics producers generator T0
Definition: gen_protons.fcl:45
std::vector< std::vector< unsigned > > OrganizeHitsIndividual(const std::vector< art::Ptr< recob::Hit >> &hits, const std::vector< const recob::TrackHitMeta * > &thms, const recob::Track &track, unsigned nplanes)
This is an interface for an art Tool which scales charge by some factor given information about its a...