EMEnergyCalib_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////////////////////
2 // Class: EMEnergyCalib
3 // Module Type: analyzer
4 // File: EMEnergyCalib_module.cc
5 // Author: Mike Wallbank (m.wallbank@sheffield.ac.uk), August 2015
6 //
7 // Analyser module to produce useful information for characterising
8 // em showers.
9 //
10 // Usage:
11 // lar -c energyCalib.fcl -s /path/to/files/with/hit/recon/*.root
12 //
13 // Description of intended use:
14 // Designed to be used to provide information for characterising showers.
15 // Also can be used along with getEnergyConversion.C macro in this directory to find the
16 // conversion between collected charge and total deposited energy for MC showers.
17 // See notes in the getEnergyConversion.C file for a description of this.
18 ////////////////////////////////////////////////////////////////////////////////////////////////
19 
20 // Framework includes:
23 #include "fhiclcpp/ParameterSet.h"
28 #include "art_root_io/TFileService.h"
29 #include "art_root_io/TFileDirectory.h"
32 
33 // LArSoft includes
47 #include "nug4/ParticleNavigation/ParticleList.h"
49 
50 // ROOT & C++ includes
51 #include <string>
52 #include <vector>
53 #include <map>
54 #include "TTree.h"
55 #include "TBranch.h"
56 #include "TLeaf.h"
57 #include "TVector3.h"
58 
59 const int kMaxHits = 10000;
60 
61 namespace emshower {
62  class EMEnergyCalib;
63 }
64 
66 public:
67 
69  void analyze(art::Event const& evt);
70  void reconfigure(fhicl::ParameterSet const& p);
71  void reset();
72  int FindTrackID(detinfo::DetectorClocksData const& clockData,
73  art::Ptr<recob::Hit> const& hit);
74 
75 private:
76 
77  // Variables for the tree
78  TTree* fTree;
79  double trueEnergy;
80  double depositU;
81  double depositV;
82  double depositZ;
87  int nhits;
92  double hit_peakT [kMaxHits];
93  double hit_charge [kMaxHits];
96 
103 
104 };
105 
107 {
108  this->reconfigure(pset);
109  fTree = tfs->make<TTree>("EMEnergyCalib","EMEnergyCalib");
110  fTree->Branch("TrueEnergy", &trueEnergy);
111  fTree->Branch("DepositU", &depositU);
112  fTree->Branch("DepositV", &depositV);
113  fTree->Branch("DepositZ", &depositZ);
114  fTree->Branch("CorrectedChargeU", &correctedChargeU);
115  fTree->Branch("CorrectedChargeV", &correctedChargeV);
116  fTree->Branch("CorrectedChargeZ", &correctedChargeZ);
117  fTree->Branch("VertexDetectorDist",&vertexDetectorDist);
118  fTree->Branch("NHits", &nhits);
119  fTree->Branch("Hit_TPC", hit_tpc, "hit_tpc[NHits]/I");
120  fTree->Branch("Hit_Plane", hit_plane, "hit_plane[NHits]/I");
121  fTree->Branch("Hit_Wire", hit_wire, "hit_wire[NHits]/I");
122  fTree->Branch("Hit_Channel", hit_channel, "hit_channel[NHits]/I");
123  fTree->Branch("Hit_PeakT", hit_peakT, "hit_peakT[NHits]/D");
124  fTree->Branch("Hit_Charge", hit_charge, "hit_charge[NHits]/D");
125  fTree->Branch("Hit_TrueTrackID", hit_truetrackid,"hit_truetrackid[NHits]/I");
126  fTree->Branch("Hit_ClusterID", hit_clusterid, "hit_clusterid[NHits]/I");
127 }
128 
130  fHitsModuleLabel = pset.get<std::string>("HitsModuleLabel");
131  fClusterModuleLabel = pset.get<std::string>("ClusterModuleLabel");
132 }
133 
135 
136  /// Analyse function to save information for calibrating shower energies
137  /// This is written assuming single particle per event
138 
139  this->reset();
140 
141  // Get the hits out of the event record
142  std::vector<art::Ptr<recob::Hit> > hits;
143  auto hitHandle = evt.getHandle<std::vector<recob::Hit> >(fHitsModuleLabel);
144  if (hitHandle)
145  art::fill_ptr_vector(hits, hitHandle);
146 
147  // Get the clusters out of the event record
148  std::vector<art::Ptr<recob::Cluster> > clusters;
149  auto clusterHandle = evt.getHandle<std::vector<recob::Cluster> >(fClusterModuleLabel);
150  if (clusterHandle)
151  art::fill_ptr_vector(clusters, clusterHandle);
152 
153  art::FindManyP<recob::Cluster> fmc(hitHandle, evt, fClusterModuleLabel);
154 
155  // Lifetime-corrected charge
156  correctedChargeU = 0;
157  correctedChargeV = 0;
158  correctedChargeZ = 0;
159 
160  // Look at the hits
161  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
162  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt, clockData);
163  for (unsigned int hitIt = 0; hitIt < hits.size(); ++hitIt) {
164 
165  if (hitIt >= kMaxHits) continue;
166 
167  // Get the hit
168  art::Ptr<recob::Hit> hit = hits.at(hitIt);
169 
170  double correctedHitCharge = ( hit->Integral() * TMath::Exp( (sampling_rate(clockData) * hit->PeakTime()) / (detProp.ElectronLifetime()*1e3) ) );
171  switch (hit->WireID().Plane) {
172  case 0:
173  correctedChargeU += correctedHitCharge;
174  break;
175  case 1:
176  correctedChargeV += correctedHitCharge;
177  break;
178  case 2:
179  correctedChargeZ += correctedHitCharge;
180  break;
181  }
182 
183  // Fill hit level info
184  hit_tpc [hitIt] = hit->WireID().TPC;
185  hit_plane [hitIt] = hit->WireID().Plane;
186  hit_wire [hitIt] = hit->WireID().Wire;
187  hit_peakT [hitIt] = hit->PeakTime();
188  hit_charge [hitIt] = hit->Integral();
189  hit_channel [hitIt] = hit->Channel();
190 
191  // Find the true track this hit is associated with
192  hit_truetrackid[hitIt] = this->FindTrackID(clockData, hit);
193 
194  // Find the cluster index this hit it associated with (-1 if unclustered)
195  if (fmc.isValid()) {
196  std::vector<art::Ptr<recob::Cluster> > clusters = fmc.at(hitIt);
197  if (clusters.size() != 0) {
198  hit_clusterid[hitIt] = clusters.at(0)->ID();
199  }
200  else hit_clusterid[hitIt] = -1;
201  }
202 
203  }
204 
205  // Event level information
206 
207  nhits = hits.size();
208 
209  const sim::ParticleList& trueParticles = particleinventory->ParticleList();
210  const simb::MCParticle* trueParticle = trueParticles.Primary(0);
211 
212  trueEnergy = trueParticle->Momentum().E();
213 
214  // Find the energy deposited on each plane in the TPC
215  const std::vector<art::Ptr< sim::SimChannel > >& simChannels = backtracker->SimChannels();
216  for (auto channelIt = simChannels.begin(); channelIt != simChannels.end(); ++channelIt) {
217  int plane = geom->View((*channelIt)->Channel());
218  for (auto const& tdcIt : (*channelIt)->TDCIDEMap()) {
219  for (auto const& ideIt : tdcIt.second) {
220  switch (plane) {
221  case geo::kU:
222  depositU += ideIt.energy;
223  break;
224  case geo::kV:
225  depositV += ideIt.energy;
226  break;
227  case geo::kZ:
228  depositZ += ideIt.energy;
229  break;
230  }
231  }
232  }
233  }
234 
235  // Find the distance between the particle vertex and the edge of the detector
236  TVector3 vertex = TVector3(trueParticle->Vx(),trueParticle->Vy(),trueParticle->Vz());
237  TVector3 end = TVector3(trueParticle->EndX(),trueParticle->EndY(),trueParticle->EndZ());
238  TVector3 direction = TVector3(trueParticle->Px(),trueParticle->Py(),trueParticle->Pz()).Unit();
239 
240  int distanceStep = 1, steps = 0;
241  TVector3 pos;
242  bool inTPC = true;
243  while (inTPC) {
244  pos = end + ( (steps*distanceStep) * direction );
245  double currentPos[3]; currentPos[0] = pos.X(); currentPos[1] = pos.Y(); currentPos[2] = pos.Z();
246  if (!geom->FindTPCAtPosition(currentPos).isValid)
247  inTPC = false;
248  ++steps;
249  }
250  vertexDetectorDist = (end - pos).Mag();
251 
252  // Put energies in GeV units
253  depositU /= 1000;
254  depositV /= 1000;
255  depositZ /= 1000;
256 
257  fTree->Fill();
258 
259  return;
260 
261 }
262 
264  art::Ptr<recob::Hit> const& hit) {
265  double particleEnergy = 0;
266  int likelyTrackID = 0;
267  std::vector<sim::TrackIDE> trackIDs = backtracker->HitToTrackIDEs(clockData, hit);
268  for (unsigned int idIt = 0; idIt < trackIDs.size(); ++idIt) {
269  if (trackIDs.at(idIt).energy > particleEnergy) {
270  particleEnergy = trackIDs.at(idIt).energy;
271  likelyTrackID = TMath::Abs(trackIDs.at(idIt).trackID);
272  }
273  }
274  return likelyTrackID;
275 }
276 
278  trueEnergy = 0;
279  depositU = 0;
280  depositV = 0;
281  depositZ = 0;
282  vertexDetectorDist = 0;
283  nhits = 0;
284  for (int hit = 0; hit < kMaxHits; ++hit) {
285  hit_tpc[hit] = 0;
286  hit_plane[hit] = 0;
287  hit_wire[hit] = 0;
288  hit_channel[hit] = 0;
289  hit_peakT[hit] = 0;
290  hit_charge[hit] = 0;
291  hit_clusterid[hit] = 0;
292  }
293 }
294 
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
double Py(const int i=0) const
Definition: MCParticle.h:231
double EndZ() const
Definition: MCParticle.h:228
Encapsulate the construction of a single cyostat.
std::vector< sim::TrackIDE > HitToTrackIDEs(detinfo::DetectorClocksData const &clockData, recob::Hit const &hit) const
art::ServiceHandle< cheat::ParticleInventoryService > particleinventory
Handle< PROD > getHandle(SelectorBase const &) const
Definition: DataViewImpl.h:382
std::string string
Definition: nybbler.cc:12
Planes which measure V.
Definition: geo_types.h:130
geo::WireID WireID() const
Definition: Hit.h:233
bool isValid
Whether this ID points to a valid element.
Definition: geo_types.h:211
double Px(const int i=0) const
Definition: MCParticle.h:230
Planes which measure Z direction.
Definition: geo_types.h:132
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
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:25
int FindTrackID(detinfo::DetectorClocksData const &clockData, art::Ptr< recob::Hit > const &hit)
Particle class.
double EndY() const
Definition: MCParticle.h:227
art framework interface to geometry description
geo::TPCID FindTPCAtPosition(double const worldLoc[3]) const
Returns the ID of the TPC at specified location.
art::ServiceHandle< cheat::BackTrackerService > backtracker
void analyze(art::Event const &evt)
const int kMaxHits
Planes which measure U.
Definition: geo_types.h:129
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
art::ServiceHandle< art::TFileService > tfs
T get(std::string const &key) const
Definition: ParameterSet.h:271
p
Definition: test.py:223
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:493
View_t View(geo::PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
Detector simulation of raw signals on wires.
const sim::ParticleList & ParticleList() const
double Vx(const int i=0) const
Definition: MCParticle.h:221
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:218
Declaration of signal hit object.
void reconfigure(fhicl::ParameterSet const &p)
Encapsulate the construction of a single detector plane.
Contains all timing reference information for the detector.
const TLorentzVector & Momentum(const int i=0) const
Definition: MCParticle.h:220
double Pz(const int i=0) const
Definition: MCParticle.h:232
double Vz(const int i=0) const
Definition: MCParticle.h:223
const std::vector< art::Ptr< sim::SimChannel > > & SimChannels() const
Tools and modules for checking out the basics of the Monte Carlo.
TCEvent evt
Definition: DataStructs.cxx:7
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:297
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:406
double EndX() const
Definition: MCParticle.h:226
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
art::ServiceHandle< geo::Geometry > geom
raw::ChannelID_t Channel() const
ID of the readout channel the hit was extracted from.
Definition: Hit.h:230
double Vy(const int i=0) const
Definition: MCParticle.h:222
Encapsulate the construction of a single detector plane.
EMEnergyCalib(fhicl::ParameterSet const &pset)
vertex reconstruction