ShowerTrackFinderCheater_tool.cc
Go to the documentation of this file.
1 //############################################################################
2 //### Name: ShowerTrackFinderCheater ###
3 //### Author: Ed Tyley ###
4 //### Date: 16.07.19 ###
5 //### Description: Cheating tool using truth for shower direction ###
6 //############################################################################
7 
8 //Framework Includes
10 
11 //LArSoft Includes
15 
16 namespace ShowerRecoTools {
17 
19 
20  public:
22 
23  //Generic Direction Finder
24  int CalculateElement(const art::Ptr<recob::PFParticle>& pfparticle,
26  reco::shower::ShowerElementHolder& ShowerEleHolder) override;
27 
28  private:
29  //Algorithm functions
31 
32  //fcl
33  const bool fDebugEVD;
36 
42  };
43 
45  : IShowerTool(pset.get<fhicl::ParameterSet>("BaseTools"))
46  , fLArPandoraShowerCheatingAlg(pset.get<fhicl::ParameterSet>("LArPandoraShowerCheatingAlg"))
47  , fDebugEVD(pset.get<bool>("DebugEVD"))
48  , fPFParticleLabel(pset.get<art::InputTag>("PFParticleLabel"))
49  , fHitModuleLabel(pset.get<art::InputTag>("HitModuleLabel"))
50  , fTrueParticleIntputLabel(pset.get<std::string>("TrueParticleIntputLabel"))
51  , fShowerStartPositionInputTag(pset.get<std::string>("ShowerStartPositionInputTag"))
52  , fShowerDirectionInputTag(pset.get<std::string>("ShowerDirectionInputTag"))
53  , fInitialTrackHitsOutputLabel(pset.get<std::string>("InitialTrackHitsOutputLabel"))
55  pset.get<std::string>("InitialTrackSpacePointsOutputLabel"))
56  {}
57 
58  int
60  art::Event& Event,
61  reco::shower::ShowerElementHolder& ShowerEleHolder)
62  {
63 
64  const simb::MCParticle* trueParticle;
65 
66  //Get the hits from the shower:
67  auto const pfpHandle = Event.getValidHandle<std::vector<recob::PFParticle>>(fPFParticleLabel);
68  auto const clockData =
70 
71  //Get the clusters
72  auto const clusHandle = Event.getValidHandle<std::vector<recob::Cluster>>(fPFParticleLabel);
73  art::FindManyP<recob::Cluster> fmc(pfpHandle, Event, fPFParticleLabel);
74  std::vector<art::Ptr<recob::Cluster>> clusters = fmc.at(pfparticle.key());
75 
76  //Get the hit association
77  art::FindManyP<recob::Hit> fmhc(clusHandle, Event, fPFParticleLabel);
78 
79  std::vector<art::Ptr<recob::Hit>> showerHits;
80  for (auto const& cluster : clusters) {
81 
82  //Get the hits
83  std::vector<art::Ptr<recob::Hit>> hits = fmhc.at(cluster.key());
84  showerHits.insert(showerHits.end(), hits.begin(), hits.end());
85  }
86 
87  if (ShowerEleHolder.CheckElement(fTrueParticleIntputLabel)) {
88  ShowerEleHolder.GetElement(fTrueParticleIntputLabel, trueParticle);
89  }
90  else {
91 
92  //Could store these in the shower element holder and just calculate once?
93  std::map<int, const simb::MCParticle*> trueParticles =
95  std::map<int, std::vector<int>> showersMothers =
97 
98  //Get the true particle from the shower
99  std::pair<int, double> ShowerTrackInfo =
101  clockData, showersMothers, showerHits, 2);
102 
103  if (ShowerTrackInfo.first == -99999) {
104  mf::LogError("ShowerStartPosition") << "True Shower Not Found";
105  return 1;
106  }
107  trueParticle = trueParticles[ShowerTrackInfo.first];
108  ShowerEleHolder.SetElement(trueParticle, fTrueParticleIntputLabel);
109  }
110 
111  if (!trueParticle) {
112  mf::LogError("ShowerDirectionCheater") << "True shower not found, returning";
113  return 1;
114  }
115 
116  //This is all based on the shower vertex being known. If it is not lets not do the track
117  if (!ShowerEleHolder.CheckElement(fShowerStartPositionInputTag)) {
118  mf::LogError("ShowerTrackFinderCheater") << "Start position not set, returning " << std::endl;
119  return 1;
120  }
121  if (!ShowerEleHolder.CheckElement(fShowerDirectionInputTag)) {
122  mf::LogError("ShowerTrackFinderCheater") << "Direction not set, returning " << std::endl;
123  return 1;
124  }
125 
126  TVector3 ShowerStartPosition = {-999, -999, -999};
127  ShowerEleHolder.GetElement(fShowerStartPositionInputTag, ShowerStartPosition);
128 
129  TVector3 ShowerDirection = {-999, -999, -999};
130  ShowerEleHolder.GetElement(fShowerDirectionInputTag, ShowerDirection);
131 
132  auto const hitHandle = Event.getValidHandle<std::vector<recob::Hit>>(fHitModuleLabel);
133 
134  // Get the hits associated with the space points
135  art::FindManyP<recob::SpacePoint> fmsph(hitHandle, Event, fPFParticleLabel);
136  if (!fmsph.isValid()) {
137  throw cet::exception("ShowerTrackFinderCheater")
138  << "Spacepoint and hit association not valid. Stopping.";
139  }
140 
141  std::vector<int> trueParticleIdVec;
142 
143  // If we have an electron, take the hits from the primary only
144  // This will also cover the cases Pandora misclassify a track as a shower
145  if (trueParticle->PdgCode() != 22) { trueParticleIdVec.push_back(trueParticle->TrackId()); }
146  else {
147  // To check if we are rolling up showers, check the number of daughters the photon has
148  const int nDaughters = trueParticle->NumberDaughters();
149  if (nDaughters == 0) {
150  // If we roll up showers, we have no choice but to take all of the hits from the photon
151  trueParticleIdVec.push_back(-trueParticle->TrackId());
152  }
153  else {
154  // If we do not roll up the showers, take all of the primary daughters
155  for (int i = 0; i < nDaughters; i++) {
156  trueParticleIdVec.push_back(trueParticle->Daughter(i));
157  }
158  }
159  }
160 
161  std::vector<art::Ptr<recob::Hit>> trackHits;
162  std::vector<art::Ptr<recob::SpacePoint>> trackSpacePoints;
163 
164  //Get the hits from the true particle
165  for (auto hit : showerHits) {
166  int trueHitId = fLArPandoraShowerCheatingAlg.TrueParticleID(clockData, hit);
167  if (std::find(trueParticleIdVec.cbegin(), trueParticleIdVec.cend(), trueHitId) !=
168  trueParticleIdVec.cend()) {
169  trackHits.push_back(hit);
170  std::vector<art::Ptr<recob::SpacePoint>> sps = fmsph.at(hit.key());
171  if (sps.size() == 1) { trackSpacePoints.push_back(sps.front()); }
172  }
173  }
174 
175  if (trackHits.empty() || trackSpacePoints.empty())
176  mf::LogWarning("ShowerTrackFinderCheater")
177  << "Creating intial track with " << trackHits.size() << " hits and "
178  << trackSpacePoints.size() << " spacepoints" << std::endl;
179 
180  ShowerEleHolder.SetElement(trackHits, fInitialTrackHitsOutputLabel);
181  ShowerEleHolder.SetElement(trackSpacePoints, fInitialTrackSpacePointsOutputLabel);
182 
183  if (fDebugEVD) {
185  clockData, trueParticle, Event, ShowerEleHolder, pfparticle);
186  }
187 
188  return 0;
189  }
190 }
191 
int PdgCode() const
Definition: MCParticle.h:212
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
std::string string
Definition: nybbler.cc:12
std::map< int, const simb::MCParticle * > GetTrueParticleMap() const
void SetElement(T &dataproduct, const std::string &Name, bool checktag=false)
STL namespace.
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
Cluster finding and building.
int NumberDaughters() const
Definition: MCParticle.h:217
int TrackId() const
Definition: MCParticle.h:210
int Daughter(const int i) const
Definition: MCParticle.cxx:112
key_type key() const noexcept
Definition: Ptr.h:216
std::map< int, std::vector< int > > GetTrueChain(std::map< int, const simb::MCParticle * > &trueParticles) const
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
bool CheckElement(const std::string &Name) const
void CheatDebugEVD(detinfo::DetectorClocksData const &clockData, const simb::MCParticle *trueParticle, art::Event const &Event, reco::shower::ShowerElementHolder &ShowerEleHolder, const art::Ptr< recob::PFParticle > &pfparticle) const
int GetElement(const std::string &Name, T &Element) const
int TrueParticleID(detinfo::DetectorClocksData const &clockData, const art::Ptr< recob::Hit > &hit) const
Detector simulation of raw signals on wires.
ShowerTrackFinderCheater(const fhicl::ParameterSet &pset)
std::pair< int, double > TrueParticleIDFromTrueChain(detinfo::DetectorClocksData const &clockData, std::map< int, std::vector< int >> const &ShowersMothers, std::vector< art::Ptr< recob::Hit >> const &hits, int planeid) const
Definition: types.h:32
int CalculateElement(const art::Ptr< recob::PFParticle > &pfparticle, art::Event &Event, reco::shower::ShowerElementHolder &ShowerEleHolder) override
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
shower::LArPandoraShowerCheatingAlg fLArPandoraShowerCheatingAlg
int bool
Definition: qglobal.h:345
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)