All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ShowerUnidirectiondEdx_tool.cc
Go to the documentation of this file.
1 //############################################################################
2 //### Name: ShowerUnidirectiondEdx ###
3 //### Author: Ed Tyley ###
4 //### Date: 13.05.19 ###
5 //### Description: Tool for finding the dEdx of the start track of the ###
6 //### shower using the standard calomitry module. Derived ###
7 //### from the EMShower_module.cc ###
8 //############################################################################
9 
10 //Framework Includes
11 #include "art/Utilities/ToolMacros.h"
12 
13 //LArSoft Includes
18 
19 namespace ShowerRecoTools {
20 
22 
23  public:
24  ShowerUnidirectiondEdx(const fhicl::ParameterSet& pset);
25 
26  //Generic Direction Finder
27  int CalculateElement(const art::Ptr<recob::PFParticle>& pfparticle,
28  art::Event& Event,
29  reco::shower::ShowerElementHolder& ShowerEleHolder) override;
30 
31  private:
32  //Define the services and algorithms
33  art::ServiceHandle<geo::Geometry> fGeom;
35 
36  //fcl parameters.
37  int fVerbose;
39  dEdxTrackLength; //Max length from a hit can be to the start point in cm.
40  bool fMaxHitPlane; //Set the best planes as the one with the most hits
41  bool fMissFirstPoint; //Do not use any hits from the first wire.
47  };
48 
49  ShowerUnidirectiondEdx::ShowerUnidirectiondEdx(const fhicl::ParameterSet& pset)
50  : IShowerTool(pset.get<fhicl::ParameterSet>("BaseTools"))
51  , fCalorimetryAlg(pset.get<fhicl::ParameterSet>("CalorimetryAlg"))
52  , fVerbose(pset.get<int>("Verbose"))
53  , fdEdxTrackLength(pset.get<float>("dEdxTrackLength"))
54  , fMaxHitPlane(pset.get<bool>("MaxHitPlane"))
55  , fMissFirstPoint(pset.get<bool>("MissFirstPoint"))
56  , fShowerStartPositionInputLabel(pset.get<std::string>("ShowerStartPositionInputLabel"))
57  , fInitialTrackHitsInputLabel(pset.get<std::string>("InitialTrackHitsInputLabel"))
58  , fShowerDirectionInputLabel(pset.get<std::string>("ShowerDirectionInputLabel"))
59  , fShowerdEdxOutputLabel(pset.get<std::string>("ShowerdEdxOutputLabel"))
60  , fShowerBestPlaneOutputLabel(pset.get<std::string>("ShowerBestPlaneOutputLabel"))
61  {}
62 
63  int
64  ShowerUnidirectiondEdx::CalculateElement(const art::Ptr<recob::PFParticle>& pfparticle,
65  art::Event& Event,
66  reco::shower::ShowerElementHolder& ShowerEleHolder)
67  {
68 
70 
71  // Shower dEdx calculation
72  if (!ShowerEleHolder.CheckElement(fShowerStartPositionInputLabel)) {
73  if (fVerbose)
74  mf::LogError("ShowerUnidirectiondEdx") << "Start position not set, returning " << std::endl;
75  return 1;
76  }
77  if (!ShowerEleHolder.CheckElement(fInitialTrackHitsInputLabel)) {
78  if (fVerbose)
79  mf::LogError("ShowerUnidirectiondEdx")
80  << "Initial Track Hits not set returning" << std::endl;
81  return 1;
82  }
83  if (!ShowerEleHolder.CheckElement(fShowerDirectionInputLabel)) {
84  if (fVerbose)
85  mf::LogError("ShowerUnidirectiondEdx") << "Shower Direction not set" << std::endl;
86  return 1;
87  }
88 
89  //Get the initial track hits
90  std::vector<art::Ptr<recob::Hit>> trackhits;
91  ShowerEleHolder.GetElement(fInitialTrackHitsInputLabel, trackhits);
92 
93  if (trackhits.empty()) {
94  if (fVerbose)
95  mf::LogWarning("ShowerUnidirectiondEdx") << "Not Hits in the initial track" << std::endl;
96  return 0;
97  }
98 
99  TVector3 ShowerStartPosition = {-999, -999, -999};
100  ShowerEleHolder.GetElement(fShowerStartPositionInputLabel, ShowerStartPosition);
101 
102  TVector3 showerDir = {-999, -999, -999};
103  ShowerEleHolder.GetElement(fShowerDirectionInputLabel, showerDir);
104 
105  geo::TPCID vtxTPC = fGeom->FindTPCAtPosition(ShowerStartPosition);
106 
107  // Split the track hits per plane
108  std::vector<double> dEdxVec;
109  std::vector<std::vector<art::Ptr<recob::Hit>>> trackHits;
110  unsigned int numPlanes = fGeom->Nplanes();
111  trackHits.resize(numPlanes);
112 
113  // Loop over the track hits and split into planes
114  for (unsigned int hitIt = 0; hitIt < trackhits.size(); ++hitIt) {
115  art::Ptr<recob::Hit> hit = trackhits.at(hitIt);
116  geo::PlaneID hitWire = hit->WireID();
117  geo::TPCID TPC = hitWire.asTPCID();
118 
119  //only get hits from the same TPC as the vertex
120  if (TPC == vtxTPC) { (trackHits.at(hitWire.Plane)).push_back(hit); }
121  }
122 
123  int bestHitsPlane = 0;
124  int bestPlaneHits = 0;
125  int bestPlane = -999;
126  double minPitch = 999;
127 
128  auto const clockData =
129  art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(Event);
130  auto const detProp =
131  art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(Event, clockData);
132 
133  for (unsigned int plane = 0; plane < numPlanes; ++plane) {
134  std::vector<art::Ptr<recob::Hit>> trackPlaneHits = trackHits.at(plane);
135 
136  if (trackPlaneHits.size()) {
137 
138  double dEdx = -999;
139  double totQ = 0;
140  double avgT = 0;
141  double pitch = 0;
142 
143  //Calculate the pitch
144  double wirepitch = fGeom->WirePitch(trackPlaneHits.at(0)->WireID().planeID());
145  double angleToVert = fGeom->WireAngleToVertical(fGeom->Plane(plane).View(),
146  trackPlaneHits[0]->WireID().planeID()) -
147  0.5 * TMath::Pi();
148  double cosgamma =
149  std::abs(std::sin(angleToVert) * showerDir.Y() + std::cos(angleToVert) * showerDir.Z());
150 
151  pitch = wirepitch / cosgamma;
152 
153  if (pitch) { // Check the pitch is calculated correctly
154  int nhits = 0;
155  std::vector<float> vQ;
156 
157  //Get the first wire
158  int w0 = trackPlaneHits.at(0)->WireID().Wire;
159 
160  for (auto const& hit : trackPlaneHits) {
161 
162  // Get the wire for each hit
163  int w1 = hit->WireID().Wire;
164  if (fMissFirstPoint && w0 == w1) { continue; }
165 
166  //Ignore hits that are too far away.
167  if (std::abs((w1 - w0) * pitch) < dEdxTrackLength) {
168  vQ.push_back(hit->Integral());
169  totQ += hit->Integral();
170  avgT += hit->PeakTime();
171  ++nhits;
172  }
173  }
174 
175  if (totQ) {
176  // Check if the pitch is the smallest yet (best plane)
177  if (pitch < minPitch) {
178  minPitch = pitch;
179  bestPlane = plane;
180  }
181 
182  //Get the median and calculate the dEdx using the algorithm.
183  double dQdx = TMath::Median(vQ.size(), &vQ[0]) / pitch;
184  dEdx = fCalorimetryAlg.dEdx_AREA(
185  clockData, detProp, dQdx, avgT / nhits, trackPlaneHits.at(0)->WireID().Plane);
186 
187  if (isinf(dEdx)) { dEdx = -999; };
188 
189  if (nhits > bestPlaneHits || ((nhits == bestPlaneHits) && (pitch < minPitch))) {
190  bestHitsPlane = plane;
191  bestPlaneHits = nhits;
192  }
193  }
194  dEdxVec.push_back(dEdx);
195  }
196  else {
197  throw cet::exception("ShowerUnidirectiondEdx")
198  << "pitch is 0. I can't think how it is 0? Stopping so I can tell you" << std::endl;
199  }
200  }
201  else { // if not (trackPlaneHits.size())
202  dEdxVec.push_back(-999);
203  }
204  trackPlaneHits.clear();
205  } //end loop over planes
206 
207  //TODO
208  std::vector<double> dEdxVecErr = {-999, -999, -999};
209 
210  ShowerEleHolder.SetElement(dEdxVec, dEdxVecErr, fShowerdEdxOutputLabel);
211 
212  //Set The best plane
213  if (fMaxHitPlane) { bestPlane = bestHitsPlane; }
214 
215  if (bestPlane == -999) {
216  throw cet::exception("ShowerUnidirectiondEdx") << "No best plane set";
217  }
218  else {
219  ShowerEleHolder.SetElement(bestPlane, fShowerBestPlaneOutputLabel);
220  }
221 
222  if (fVerbose > 1) {
223  std::cout << "Best Plane: " << bestPlane << std::endl;
224  for (unsigned int plane = 0; plane < dEdxVec.size(); plane++) {
225  std::cout << "Plane: " << plane << " with dEdx: " << dEdxVec[plane] << std::endl;
226  }
227  }
228 
229  return 0;
230  }
231 }
232 
233 DEFINE_ART_CLASS_TOOL(ShowerRecoTools::ShowerUnidirectiondEdx)
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
Definition: UtilFunc.cxx:42
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
void SetElement(T &dataproduct, const std::string &Name, bool checktag=false)
ShowerUnidirectiondEdx(const fhicl::ParameterSet &pset)
static constexpr bool
process_name hit
Definition: cheaterreco.fcl:51
BEGIN_PROLOG TPC
T abs(T value)
art::ServiceHandle< geo::Geometry > fGeom
bool CheckElement(const std::string &Name) const
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
int GetElement(const std::string &Name, T &Element) const
int CalculateElement(const art::Ptr< recob::PFParticle > &pfparticle, art::Event &Event, reco::shower::ShowerElementHolder &ShowerEleHolder) override
float dEdx(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const TCSlice &slc, TP3D &tp3d)
Definition: PFPUtils.cxx:2687
constexpr TPCID const & asTPCID() const
Conversion to TPCID (for convenience of notation).
Definition: geo_types.h:446
double dEdx_AREA(detinfo::DetectorClocksData const &clock_data, detinfo::DetectorPropertiesData const &det_prop, recob::Hit const &hit, double pitch, double T0=0) const
BEGIN_PROLOG could also be cout
auto const detProp