Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
ShowerNumElectronsEnergy_tool.cc
Go to the documentation of this file.
1//############################################################################
2//### Name: ShowerNumElectronsEnergy ###
3//### Author: Tom Ham ###
4//### Date: 01/04/2020 ###
5//### Description: Tool for finding the Energy of the shower by going ###
6//### from number of hits -> number of electrons -> energy. ###
7//### Derived from the linear energy algorithm, written for ###
8//### the EMShower_module.cc ###
9//############################################################################
10
11//Framework Includes
12#include "art/Utilities/ToolMacros.h"
13
14//LArSoft Includes
15#include "larcoreobj/SimpleTypesAndConstants/PhysicalConstants.h"
16#include "lardata/DetectorInfoServices/DetectorClocksService.h"
17#include "lardata/DetectorInfoServices/DetectorPropertiesService.h"
18#include "lardataobj/RecoBase/Cluster.h"
19#include "lardataobj/RecoBase/PFParticle.h"
21#include "larreco/Calorimetry/CalorimetryAlg.h"
22
23//C++ Includes
24#include <tuple>
25
26namespace ShowerRecoTools {
27
29
30 public:
31 ShowerNumElectronsEnergy(const fhicl::ParameterSet& pset);
32
33 //Physics Function. Calculate the shower Energy.
34 int CalculateElement(const art::Ptr<recob::PFParticle>& pfparticle,
35 art::Event& Event,
36 reco::shower::ShowerElementHolder& ShowerElementHolder) override;
37
38 private:
39 double CalculateEnergy(const detinfo::DetectorClocksData& clockData,
40 const detinfo::DetectorPropertiesData& detProp,
41 const std::vector<art::Ptr<recob::Hit>>& hits,
42 const geo::PlaneID::PlaneID_t plane) const;
43
44 art::InputTag fPFParticleLabel;
46
49
50 //Services
51 art::ServiceHandle<geo::Geometry> fGeom;
52 calo::CalorimetryAlg fCalorimetryAlg;
53
54 // Declare stuff
56 };
57
59 : IShowerTool(pset.get<fhicl::ParameterSet>("BaseTools"))
60 , fPFParticleLabel(pset.get<art::InputTag>("PFParticleLabel"))
61 , fVerbose(pset.get<int>("Verbose"))
62 , fShowerEnergyOutputLabel(pset.get<std::string>("ShowerEnergyOutputLabel"))
63 , fShowerBestPlaneOutputLabel(pset.get<std::string>("ShowerBestPlaneOutputLabel"))
64 , fCalorimetryAlg(pset.get<fhicl::ParameterSet>("CalorimetryAlg"))
65 , fRecombinationFactor(pset.get<double>("RecombinationFactor"))
66 {}
67
68 int ShowerNumElectronsEnergy::CalculateElement(const art::Ptr<recob::PFParticle>& pfparticle,
69 art::Event& Event,
70 reco::shower::ShowerElementHolder& ShowerEleHolder)
71 {
72
73 if (fVerbose)
74 std::cout
75 << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Shower Reco Energy Tool ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
76 << std::endl;
77
78 // Get the assocated pfParicle vertex PFParticles
79 auto const pfpHandle = Event.getValidHandle<std::vector<recob::PFParticle>>(fPFParticleLabel);
80
81 //Get the clusters
82 auto const clusHandle = Event.getValidHandle<std::vector<recob::Cluster>>(fPFParticleLabel);
83
84 const art::FindManyP<recob::Cluster>& fmc =
85 ShowerEleHolder.GetFindManyP<recob::Cluster>(pfpHandle, Event, fPFParticleLabel);
86 // art::FindManyP<recob::Cluster> fmc(pfpHandle, Event, fPFParticleLabel);
87 std::vector<art::Ptr<recob::Cluster>> clusters = fmc.at(pfparticle.key());
88
89 //Get the hit association
90 const art::FindManyP<recob::Hit>& fmhc =
91 ShowerEleHolder.GetFindManyP<recob::Hit>(clusHandle, Event, fPFParticleLabel);
92 // art::FindManyP<recob::Hit> fmhc(clusHandle, Event, fPFParticleLabel);
93
94 std::map<geo::PlaneID::PlaneID_t, std::vector<art::Ptr<recob::Hit>>> planeHits;
95
96 //Loop over the clusters in the plane and get the hits
97 for (auto const& cluster : clusters) {
98
99 //Get the hits
100 std::vector<art::Ptr<recob::Hit>> hits = fmhc.at(cluster.key());
101
102 //Get the plane.
103 const geo::PlaneID::PlaneID_t plane(cluster->Plane().Plane);
104
105 planeHits[plane].insert(planeHits[plane].end(), hits.begin(), hits.end());
106 }
107
108 // Calculate the energy for each plane && best plane
109 geo::PlaneID::PlaneID_t bestPlane = std::numeric_limits<geo::PlaneID::PlaneID_t>::max();
110 unsigned int bestPlaneNumHits = 0;
111
112 //Holder for the final product
113 std::vector<double> energyVec(fGeom->Nplanes(), -999.);
114 std::vector<double> energyError(fGeom->Nplanes(), -999.);
115
116 auto const clockData =
117 art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(Event);
118 auto const detProp =
119 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(Event, clockData);
120
121 for (auto const& [plane, hits] : planeHits) {
122
123 unsigned int planeNumHits = hits.size();
124
125 //Calculate the Energy for
126 double Energy = CalculateEnergy(clockData, detProp, hits, plane);
127 // If the energy is negative, leave it at -999
128 if (Energy > 0) energyVec.at(plane) = Energy;
129
130 if (planeNumHits > bestPlaneNumHits) {
131 bestPlane = plane;
132 bestPlaneNumHits = planeNumHits;
133 }
134 }
135
136 ShowerEleHolder.SetElement(energyVec, energyError, fShowerEnergyOutputLabel);
137 // Only set the best plane if it has some hits in it
138 if (bestPlane < fGeom->Nplanes()) {
139 // Need to cast as an int for legacy default of -999
140 // have to define a new variable as we pass-by-reference when filling
141 int bestPlaneVal(bestPlane);
142 ShowerEleHolder.SetElement(bestPlaneVal, fShowerBestPlaneOutputLabel);
143 }
144
145 return 0;
146 }
147
148 // function to calculate the reco energy
149 double ShowerNumElectronsEnergy::CalculateEnergy(const detinfo::DetectorClocksData& clockData,
150 const detinfo::DetectorPropertiesData& detProp,
151 const std::vector<art::Ptr<recob::Hit>>& hits,
152 const geo::PlaneID::PlaneID_t plane) const
153 {
154
155 double totalCharge = 0;
156 double totalEnergy = 0;
157 double correctedtotalCharge = 0;
158 double nElectrons = 0;
159
160 for (auto const& hit : hits) {
161 totalCharge +=
162 hit->Integral() *
163 fCalorimetryAlg.LifetimeCorrection(
164 clockData, detProp, hit->PeakTime()); // obtain charge and correct for lifetime
165 }
166
167 // correct charge due to recombination
168 correctedtotalCharge = totalCharge / fRecombinationFactor;
169 // calculate # of electrons and the corresponding energy
170 nElectrons = fCalorimetryAlg.ElectronsFromADCArea(correctedtotalCharge, plane);
171 totalEnergy = (nElectrons / util::kGeVToElectrons) * 1000; // energy in MeV
172 return totalEnergy;
173 }
174}
175
ShowerNumElectronsEnergy(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
int CalculateElement(const art::Ptr< recob::PFParticle > &pfparticle, art::Event &Event, reco::shower::ShowerElementHolder &ShowerElementHolder) override
const art::FindManyP< T1 > & GetFindManyP(const art::ValidHandle< std::vector< T2 > > &handle, const art::Event &evt, const art::InputTag &moduleTag)
void SetElement(T &dataproduct, const std::string &Name, bool checktag=false)