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
12 
13 //LArSoft Includes
16 
17 namespace ShowerRecoTools {
18 
20 
21  public:
23 
24  //Generic Direction Finder
25  int CalculateElement(const art::Ptr<recob::PFParticle>& pfparticle,
27  reco::shower::ShowerElementHolder& ShowerEleHolder) override;
28 
29  private:
30  //Define the services and algorithms
33 
34  //fcl parameters.
35  int fVerbose;
37  dEdxTrackLength; //Max length from a hit can be to the start point in cm.
38  bool fMaxHitPlane; //Set the best planes as the one with the most hits
39  bool fMissFirstPoint; //Do not use any hits from the first wire.
45  };
46 
48  : IShowerTool(pset.get<fhicl::ParameterSet>("BaseTools"))
49  , fCalorimetryAlg(pset.get<fhicl::ParameterSet>("CalorimetryAlg"))
50  , fVerbose(pset.get<int>("Verbose"))
51  , fdEdxTrackLength(pset.get<float>("dEdxTrackLength"))
52  , fMaxHitPlane(pset.get<bool>("MaxHitPlane"))
53  , fMissFirstPoint(pset.get<bool>("MissFirstPoint"))
54  , fShowerStartPositionInputLabel(pset.get<std::string>("ShowerStartPositionInputLabel"))
55  , fInitialTrackHitsInputLabel(pset.get<std::string>("InitialTrackHitsInputLabel"))
56  , fShowerDirectionInputLabel(pset.get<std::string>("ShowerDirectionInputLabel"))
57  , fShowerdEdxOutputLabel(pset.get<std::string>("ShowerdEdxOutputLabel"))
58  , fShowerBestPlaneOutputLabel(pset.get<std::string>("ShowerBestPlaneOutputLabel"))
59  {}
60 
61  int
63  art::Event& Event,
64  reco::shower::ShowerElementHolder& ShowerEleHolder)
65  {
66 
68 
69  // Shower dEdx calculation
70  if (!ShowerEleHolder.CheckElement(fShowerStartPositionInputLabel)) {
71  if (fVerbose)
72  mf::LogError("ShowerUnidirectiondEdx") << "Start position not set, returning " << std::endl;
73  return 1;
74  }
75  if (!ShowerEleHolder.CheckElement(fInitialTrackHitsInputLabel)) {
76  if (fVerbose)
77  mf::LogError("ShowerUnidirectiondEdx")
78  << "Initial Track Hits not set returning" << std::endl;
79  return 1;
80  }
81  if (!ShowerEleHolder.CheckElement(fShowerDirectionInputLabel)) {
82  if (fVerbose)
83  mf::LogError("ShowerUnidirectiondEdx") << "Shower Direction not set" << std::endl;
84  return 1;
85  }
86 
87  //Get the initial track hits
88  std::vector<art::Ptr<recob::Hit>> trackhits;
89  ShowerEleHolder.GetElement(fInitialTrackHitsInputLabel, trackhits);
90 
91  if (trackhits.empty()) {
92  if (fVerbose)
93  mf::LogWarning("ShowerUnidirectiondEdx") << "Not Hits in the initial track" << std::endl;
94  return 0;
95  }
96 
97  TVector3 ShowerStartPosition = {-999, -999, -999};
98  ShowerEleHolder.GetElement(fShowerStartPositionInputLabel, ShowerStartPosition);
99 
100  TVector3 showerDir = {-999, -999, -999};
101  ShowerEleHolder.GetElement(fShowerDirectionInputLabel, showerDir);
102 
103  geo::TPCID vtxTPC = fGeom->FindTPCAtPosition(ShowerStartPosition);
104 
105  // Split the track hits per plane
106  std::vector<double> dEdxVec;
107  std::vector<std::vector<art::Ptr<recob::Hit>>> trackHits;
108  unsigned int numPlanes = fGeom->Nplanes();
109  trackHits.resize(numPlanes);
110 
111  // Loop over the track hits and split into planes
112  for (unsigned int hitIt = 0; hitIt < trackhits.size(); ++hitIt) {
113  art::Ptr<recob::Hit> hit = trackhits.at(hitIt);
114  geo::PlaneID hitWire = hit->WireID();
115  geo::TPCID TPC = hitWire.asTPCID();
116 
117  //only get hits from the same TPC as the vertex
118  if (TPC == vtxTPC) { (trackHits.at(hitWire.Plane)).push_back(hit); }
119  }
120 
121  int bestHitsPlane = 0;
122  int bestPlaneHits = 0;
123  int bestPlane = -999;
124  double minPitch = 999;
125 
126  auto const clockData =
128  auto const detProp =
130 
131  for (unsigned int plane = 0; plane < numPlanes; ++plane) {
132  std::vector<art::Ptr<recob::Hit>> trackPlaneHits = trackHits.at(plane);
133 
134  if (trackPlaneHits.size()) {
135 
136  double dEdx = -999;
137  double totQ = 0;
138  double avgT = 0;
139  double pitch = 0;
140 
141  //Calculate the pitch
142  double wirepitch = fGeom->WirePitch(trackPlaneHits.at(0)->WireID().planeID());
143  double angleToVert = fGeom->WireAngleToVertical(fGeom->Plane(plane).View(),
144  trackPlaneHits[0]->WireID().planeID()) -
145  0.5 * TMath::Pi();
146  double cosgamma =
147  std::abs(std::sin(angleToVert) * showerDir.Y() + std::cos(angleToVert) * showerDir.Z());
148 
149  pitch = wirepitch / cosgamma;
150 
151  if (pitch) { // Check the pitch is calculated correctly
152  int nhits = 0;
153  std::vector<float> vQ;
154 
155  //Get the first wire
156  int w0 = trackPlaneHits.at(0)->WireID().Wire;
157 
158  for (auto const& hit : trackPlaneHits) {
159 
160  // Get the wire for each hit
161  int w1 = hit->WireID().Wire;
162  if (fMissFirstPoint && w0 == w1) { continue; }
163 
164  //Ignore hits that are too far away.
165  if (std::abs((w1 - w0) * pitch) < dEdxTrackLength) {
166  vQ.push_back(hit->Integral());
167  totQ += hit->Integral();
168  avgT += hit->PeakTime();
169  ++nhits;
170  }
171  }
172 
173  if (totQ) {
174  // Check if the pitch is the smallest yet (best plane)
175  if (pitch < minPitch) {
176  minPitch = pitch;
177  bestPlane = plane;
178  }
179 
180  //Get the median and calculate the dEdx using the algorithm.
181  double dQdx = TMath::Median(vQ.size(), &vQ[0]) / pitch;
182  dEdx = fCalorimetryAlg.dEdx_AREA(
183  clockData, detProp, dQdx, avgT / nhits, trackPlaneHits.at(0)->WireID().Plane);
184 
185  if (isinf(dEdx)) { dEdx = -999; };
186 
187  if (nhits > bestPlaneHits || ((nhits == bestPlaneHits) && (pitch < minPitch))) {
188  bestHitsPlane = plane;
189  bestPlaneHits = nhits;
190  }
191  }
192  dEdxVec.push_back(dEdx);
193  }
194  else {
195  throw cet::exception("ShowerUnidirectiondEdx")
196  << "pitch is 0. I can't think how it is 0? Stopping so I can tell you" << std::endl;
197  }
198  }
199  else { // if not (trackPlaneHits.size())
200  dEdxVec.push_back(-999);
201  }
202  trackPlaneHits.clear();
203  } //end loop over planes
204 
205  //TODO
206  std::vector<double> dEdxVecErr = {-999, -999, -999};
207 
208  ShowerEleHolder.SetElement(dEdxVec, dEdxVecErr, fShowerdEdxOutputLabel);
209 
210  //Set The best plane
211  if (fMaxHitPlane) { bestPlane = bestHitsPlane; }
212 
213  if (bestPlane == -999) {
214  throw cet::exception("ShowerUnidirectiondEdx") << "No best plane set";
215  }
216  else {
217  ShowerEleHolder.SetElement(bestPlane, fShowerBestPlaneOutputLabel);
218  }
219 
220  if (fVerbose > 1) {
221  std::cout << "Best Plane: " << bestPlane << std::endl;
222  for (unsigned int plane = 0; plane < dEdxVec.size(); plane++) {
223  std::cout << "Plane: " << plane << " with dEdx: " << dEdxVec[plane] << std::endl;
224  }
225  }
226 
227  return 0;
228  }
229 }
230 
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
PlaneGeo const & Plane(unsigned int const p, unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified wire.
std::string string
Definition: nybbler.cc:12
geo::WireID WireID() const
Definition: Hit.h:233
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)
STL namespace.
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
geo::TPCID FindTPCAtPosition(double const worldLoc[3]) const
Returns the ID of the TPC at specified location.
T abs(T value)
View_t View() const
Which coordinate does this plane measure.
Definition: PlaneGeo.h:184
double dEdx(float dqdx, float Efield)
Definition: doAna.cpp:21
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
fInnerVessel push_back(Point(-578.400000, 0.000000, 0.000000))
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
Detector simulation of raw signals on wires.
constexpr TPCID const & asTPCID() const
Conversion to TPCID (for convenience of notation).
Definition: geo_types.h:446
Definition: types.h:32
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
double dEdx_AREA(detinfo::DetectorClocksData const &clock_data, detinfo::DetectorPropertiesData const &det_prop, recob::Hit const &hit, double pitch, double T0=0) const
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
int bool
Definition: qglobal.h:345
double WireAngleToVertical(geo::View_t view, geo::TPCID const &tpcid) const
Returns the angle of the wires in the specified view from vertical.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)