LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
ShowerLinearEnergy_tool.cc
Go to the documentation of this file.
1 //############################################################################
2 //### Name: ShowerLinearEnergy ###
3 //### Author: Dominic Barker ###
4 //### Date: 13.05.19 ###
5 //### Description: Tool for finding the Energy of the shower. Derived ###
6 //### from the linear energy algorithm, written for ###
7 //### the EMShower_module.cc ###
8 //############################################################################
9 
10 //Framework Includes
12 
13 //LArSoft Includes
20 
21 namespace ShowerRecoTools {
22 
24 
25  public:
27 
28  //Physics Function. Calculate the shower Energy.
29  int CalculateElement(const art::Ptr<recob::PFParticle>& pfparticle,
30  art::Event& Event,
31  reco::shower::ShowerElementHolder& ShowerElementHolder) override;
32 
33  private:
34  double CalculateEnergy(const detinfo::DetectorClocksData& clockData,
35  const detinfo::DetectorPropertiesData& detProp,
37  const geo::PlaneID::PlaneID_t plane) const;
38 
39  //fcl parameters
40  unsigned int fNumPlanes;
41  std::vector<double> fGradients; //Gradient of the linear fit of total charge to total energy
42  std::vector<double> fIntercepts; //Intercept of the linear fit of total charge to total energy
43 
45  int fVerbose;
46 
49 
50  //Services
52  };
53 
55  : IShowerTool(pset.get<fhicl::ParameterSet>("BaseTools"))
56  , fGradients(pset.get<std::vector<double>>("Gradients"))
57  , fIntercepts(pset.get<std::vector<double>>("Intercepts"))
58  , fPFParticleLabel(pset.get<art::InputTag>("PFParticleLabel"))
59  , fVerbose(pset.get<int>("Verbose"))
60  , fShowerEnergyOutputLabel(pset.get<std::string>("ShowerEnergyOutputLabel"))
61  , fShowerBestPlaneOutputLabel(pset.get<std::string>("ShowerBestPlaneOutputLabel"))
62  {
64  if (fNumPlanes != fGradients.size() || fNumPlanes != fIntercepts.size()) {
65  throw cet::exception("ShowerLinearEnergy")
66  << "The number of planes does not match the size of the fcl parametes passed: Num Planes: "
67  << fNumPlanes << ", Gradients size: " << fGradients.size()
68  << ", Intercpts size: " << fIntercepts.size();
69  }
70  }
71 
73  art::Event& Event,
74  reco::shower::ShowerElementHolder& ShowerEleHolder)
75  {
76 
77  // Get the assocated pfParicle vertex PFParticles
78  auto const pfpHandle = Event.getValidHandle<std::vector<recob::PFParticle>>(fPFParticleLabel);
79 
80  //Get the clusters
81  auto const clusHandle = Event.getValidHandle<std::vector<recob::Cluster>>(fPFParticleLabel);
82 
84  ShowerEleHolder.GetFindManyP<recob::Cluster>(pfpHandle, Event, fPFParticleLabel);
85  // art::FindManyP<recob::Cluster> fmc(pfpHandle, Event, fPFParticleLabel);
86  std::vector<art::Ptr<recob::Cluster>> clusters = fmc.at(pfparticle.key());
87 
88  //Get the hit association
89  const art::FindManyP<recob::Hit>& fmhc =
90  ShowerEleHolder.GetFindManyP<recob::Hit>(clusHandle, Event, fPFParticleLabel);
91  // art::FindManyP<recob::Hit> fmhc(clusHandle, Event, fPFParticleLabel);
92 
93  std::map<geo::PlaneID::PlaneID_t, std::vector<art::Ptr<recob::Hit>>> planeHits;
94 
95  //Loop over the clusters in the plane and get the hits
96  for (auto const& cluster : clusters) {
97 
98  //Get the hits
99  std::vector<art::Ptr<recob::Hit>> hits = fmhc.at(cluster.key());
100 
101  //Get the plane.
102  const geo::PlaneID::PlaneID_t plane(cluster->Plane().Plane);
103 
104  planeHits[plane].insert(planeHits[plane].end(), hits.begin(), hits.end());
105  }
106 
107  // Calculate the energy for each plane && best plane
108  geo::PlaneID::PlaneID_t bestPlane = std::numeric_limits<geo::PlaneID::PlaneID_t>::max();
109  unsigned int bestPlaneNumHits = 0;
110 
111  //Holder for the final product
112  std::vector<double> energyVec(fNumPlanes, -999.);
113  std::vector<double> energyError(fNumPlanes, -999.);
114 
115  auto const clockData =
117  auto const detProp =
119 
120  for (auto const& [plane, hits] : planeHits) {
121 
122  unsigned int planeNumHits = hits.size();
123 
124  //Calculate the Energy for
125  double Energy = CalculateEnergy(clockData, detProp, hits, plane);
126  // If the energy is negative, leave it at -999
127  if (Energy > 0) energyVec.at(plane) = Energy;
128 
129  if (planeNumHits > bestPlaneNumHits) {
130  bestPlane = plane;
131  bestPlaneNumHits = planeNumHits;
132  }
133  }
134 
135  ShowerEleHolder.SetElement(energyVec, energyError, fShowerEnergyOutputLabel);
136  // Only set the best plane if it has some hits in it
137  if (bestPlane < fGeom->Nplanes()) {
138  // Need to cast as an int for legacy default of -999
139  // have to define a new variable as we pass-by-reference when filling
140  int bestPlaneVal(bestPlane);
141  ShowerEleHolder.SetElement(bestPlaneVal, fShowerBestPlaneOutputLabel);
142  }
143 
144  return 0;
145  }
146 
147  //Function to calculate the energy of a shower in a plane. Using a linear map between charge and Energy.
148  //Exactly the same method as the ShowerEnergyAlg.cxx. Thanks Mike.
150  const detinfo::DetectorPropertiesData& detProp,
152  const geo::PlaneID::PlaneID_t plane) const
153  {
154 
155  double totalCharge = 0, totalEnergy = 0;
156 
157  for (auto const& hit : hits) {
158  totalCharge += (hit->Integral() * std::exp((sampling_rate(clockData) * hit->PeakTime()) /
159  (detProp.ElectronLifetime() * 1e3)));
160  }
161 
162  totalEnergy = (totalCharge * fGradients.at(plane)) + fIntercepts.at(plane);
163 
164  return totalEnergy;
165  }
166 }
167 
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
ShowerLinearEnergy(const fhicl::ParameterSet &pset)
double CalculateEnergy(const detinfo::DetectorClocksData &clockData, const detinfo::DetectorPropertiesData &detProp, const std::vector< art::Ptr< recob::Hit >> &hits, const geo::PlaneID::PlaneID_t plane) const
Declaration of signal hit object.
unsigned int PlaneID_t
Type for the ID number.
Definition: geo_types.h:464
void SetElement(T &dataproduct, const std::string &Name, bool checktag=false)
STL namespace.
Set of hits with a 2D structure.
Definition: Cluster.h:69
art::ServiceHandle< geo::Geometry > fGeom
Cluster finding and building.
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:289
void hits()
Definition: readHits.C:15
parameter set interface
key_type key() const noexcept
Definition: Ptr.h:166
Declaration of cluster object.
Detector simulation of raw signals on wires.
int CalculateElement(const art::Ptr< recob::PFParticle > &pfparticle, art::Event &Event, reco::shower::ShowerElementHolder &ShowerElementHolder) override
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
decltype(auto) get(T &&obj)
ADL-aware version of std::to_string.
Definition: StdUtils.h:120
Contains all timing reference information for the detector.
Definition: MVAAlg.h:12
unsigned int Nplanes(TPCID const &tpcid=tpc_zero) const
Returns the total number of planes in the specified TPC.
Definition: GeometryCore.h:977
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:46
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
const art::FindManyP< T1 > & GetFindManyP(const art::ValidHandle< std::vector< T2 >> &handle, const art::Event &evt, const art::InputTag &moduleTag)
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33