LArPandoraShowerCheatingAlg.cxx
Go to the documentation of this file.
2 
4  : fLArPandoraShowerAlg(pset.get<fhicl::ParameterSet>("LArPandoraShowerAlg"))
5  , fHitModuleLabel(pset.get<art::InputTag>("HitModuleLabel"))
6  , fPFParticleLabel(pset.get<art::InputTag>("PFParticleLabel"))
7  , fShowerStartPositionInputLabel(pset.get<std::string>("ShowerStartPositionInputLabel"))
8  , fShowerDirectionInputLabel(pset.get<std::string>("ShowerDirectionInputLabel"))
9  , fInitialTrackSpacePointsInputLabel(pset.get<std::string>("InitialTrackSpacePointsInputLabel"))
10 {}
11 
12 std::map<int, const simb::MCParticle*>
14 {
15 
16  const sim::ParticleList& particles = particleInventory->ParticleList();
17 
18  std::map<int, const simb::MCParticle*> trueParticles;
19  // Make a map of track id to particle
20  for (sim::ParticleList::const_iterator particleIt = particles.begin();
21  particleIt != particles.end();
22  ++particleIt) {
23  const simb::MCParticle* particle = particleIt->second;
24  trueParticles[particle->TrackId()] = particle;
25  //std::cout<<"Particle ID: "<<particle->TrackId()<<" and PDG: "<<particle->PdgCode()<<std::endl;
26  }
27  return trueParticles;
28 }
29 
30 std::map<int, std::vector<int>>
32  std::map<int, const simb::MCParticle*>& trueParticles) const
33 {
34 
35  // Roll up showers if not already done:
36  std::map<int, std::vector<int>> showerMothers;
37 
38  // Loop over daughters and find th`e mothers
39  for (const auto& particleIt : trueParticles) {
40  const simb::MCParticle* particle = particleIt.second;
41  const simb::MCParticle* mother = particle;
42 
43  if (std::abs(particle->PdgCode()) != 11 && std::abs(particle->PdgCode()) != 22) { continue; }
44 
45  // While the grand mother exists and is an electron or photon
46  // Note the true mother will skip this loop and fill itself into the map
47  while (mother->Mother() != 0 && trueParticles.find(mother->Mother()) != trueParticles.end()) {
48 
49  int motherId = mother->Mother();
50  if (std::abs(trueParticles[motherId]->PdgCode()) != 11 &&
51  std::abs(trueParticles[motherId]->PdgCode()) != 22) {
52  break;
53  }
54  mother = trueParticles[motherId];
55  }
56  showerMothers[mother->TrackId()].push_back(particle->TrackId());
57  }
58  return showerMothers;
59 }
60 
61 void
63  detinfo::DetectorClocksData const& clockData,
64  const simb::MCParticle* trueParticle,
65  art::Event const& Event,
66  reco::shower::ShowerElementHolder& ShowerEleHolder,
67  const art::Ptr<recob::PFParticle>& pfparticle) const
68 {
69 
70  std::cout << "Making Debug Event Display" << std::endl;
71 
72  //Function for drawing reco showers to check direction and initial track selection
73 
74  // Get run info to make unique canvas names
75  int run = Event.run();
76  int subRun = Event.subRun();
77  int event = Event.event();
78  int PFPID = pfparticle->Self();
79 
80  // Create the canvas
81  TString canvasName = Form("canvas_%i_%i_%i_%i", run, subRun, event, PFPID);
82  TCanvas* canvas = tfs->make<TCanvas>(canvasName, canvasName);
83 
84  // Initialise variables
85  double x = 0;
86  double y = 0;
87  double z = 0;
88 
89  std::vector<art::Ptr<recob::SpacePoint>> showerSpacePoints;
90  std::vector<art::Ptr<recob::SpacePoint>> otherSpacePoints;
91 
92  auto const hitHandle = Event.getValidHandle<std::vector<recob::Hit>>(fHitModuleLabel);
93  std::vector<art::Ptr<recob::Hit>> hits;
94  art::fill_ptr_vector(hits, hitHandle);
95 
96  // Get the hits associated with the space points
97  const art::FindManyP<recob::SpacePoint> fmsph(hitHandle, Event, fPFParticleLabel);
98  if (!fmsph.isValid()) {
99  throw cet::exception("LArPandoraShowerCheatingAlg")
100  << "Spacepoint and hit association not valid. Stopping.";
101  }
102 
103  std::map<art::Ptr<recob::SpacePoint>, art::Ptr<recob::Hit>> spacePointHitMap;
104  //Get the hits from the true particle
105  for (auto hit : hits) {
106  int trueParticleID = std::abs(TrueParticleID(clockData, hit));
107  std::vector<art::Ptr<recob::SpacePoint>> sps = fmsph.at(hit.key());
108  if (sps.size() == 1) {
109  art::Ptr<recob::SpacePoint> sp = sps.front();
110  if (trueParticleID == trueParticle->TrackId()) { showerSpacePoints.push_back(sp); }
111  else {
112  otherSpacePoints.push_back(sp);
113  }
114  }
115  }
116 
117  if (!ShowerEleHolder.CheckElement(fShowerStartPositionInputLabel)) {
118  mf::LogError("LArPandoraShowerCheatingAlg")
119  << "Start position not set, returning " << std::endl;
120  return;
121  }
122  if (!ShowerEleHolder.CheckElement(fShowerDirectionInputLabel)) {
123  mf::LogError("LArPandoraShowerCheatingAlg") << "Direction not set, returning " << std::endl;
124  return;
125  }
126  if (!ShowerEleHolder.CheckElement(fInitialTrackSpacePointsInputLabel)) {
127  mf::LogError("LArPandoraShowerCheatingAlg")
128  << "TrackSpacePoints not set, returning " << std::endl;
129  return;
130  }
131 
132  // Get info from shower property holder
133  TVector3 showerStartPosition = {-999, -999, -999};
134  TVector3 showerDirection = {-999, -999, -999};
135  std::vector<art::Ptr<recob::SpacePoint>> trackSpacePoints;
136 
137  ShowerEleHolder.GetElement(fShowerStartPositionInputLabel, showerStartPosition);
138  ShowerEleHolder.GetElement(fShowerDirectionInputLabel, showerDirection);
139  ShowerEleHolder.GetElement(fInitialTrackSpacePointsInputLabel, trackSpacePoints);
140 
141  // Create 3D point at vertex, chosed to be origin for ease of use of display
142  double startXYZ[3] = {0, 0, 0};
143  auto startPoly = std::make_unique<TPolyMarker3D>(1, startXYZ);
144 
145  // Get the min and max projections along the direction to know how long to draw
146  // the direction line
147  double minProj = std::numeric_limits<double>::max();
148  double maxProj = -std::numeric_limits<double>::max();
149 
153 
154  //initialise counter point
155  int point = 0;
156 
157  // Make 3D points for each spacepoint in the shower
158  auto showerPoly = std::make_unique<TPolyMarker3D>(showerSpacePoints.size());
159  for (auto spacePoint : showerSpacePoints) {
160  TVector3 pos = fLArPandoraShowerAlg.SpacePointPosition(spacePoint) - showerStartPosition;
161 
162  x = pos.X();
163  y = pos.Y();
164  z = pos.Z();
165  x_min = std::min(x, x_min);
166  x_max = std::max(x, x_max);
167  y_min = std::min(y, y_min);
168  y_max = std::max(y, y_max);
169  z_min = std::min(z, z_min);
170  z_max = std::max(z, z_max);
171 
172  showerPoly->SetPoint(point, x, y, z);
173  ++point;
174 
175  // Calculate the projection of (point-startpoint) along the direction
176  double proj =
177  fLArPandoraShowerAlg.SpacePointProjection(spacePoint, showerStartPosition, showerDirection);
178 
179  maxProj = std::max(proj, maxProj);
180  minProj = std::min(proj, minProj);
181  } // loop over spacepoints
182 
183  // Create TPolyLine3D arrays
184  double xDirPoints[2] = {minProj * showerDirection.X(), maxProj * showerDirection.X()};
185  double yDirPoints[2] = {minProj * showerDirection.Y(), maxProj * showerDirection.Y()};
186  double zDirPoints[2] = {minProj * showerDirection.Z(), maxProj * showerDirection.Z()};
187 
188  auto dirPoly = std::make_unique<TPolyLine3D>(2, xDirPoints, yDirPoints, zDirPoints);
189 
190  point = 0; // re-initialise counter
191  auto trackPoly = std::make_unique<TPolyMarker3D>(trackSpacePoints.size());
192  for (auto spacePoint : trackSpacePoints) {
193  TVector3 pos = fLArPandoraShowerAlg.SpacePointPosition(spacePoint) - showerStartPosition;
194  x = pos.X();
195  y = pos.Y();
196  z = pos.Z();
197  trackPoly->SetPoint(point, x, y, z);
198  ++point;
199  } // loop over track spacepoints
200 
201  // we want to draw all of the PFParticles in the event
202  //Get the PFParticles
203 
204  auto otherPoly = std::make_unique<TPolyMarker3D>(otherSpacePoints.size());
205 
206  // initialise counters
207  point = 0; // re-initialise counter
208 
209  for (auto const& sp : otherSpacePoints) {
210  TVector3 pos = fLArPandoraShowerAlg.SpacePointPosition(sp) - showerStartPosition;
211  x = pos.X();
212  y = pos.Y();
213  z = pos.Z();
214  x_min = std::min(x, x_min);
215  x_max = std::max(x, x_max);
216  y_min = std::min(y, y_min);
217  y_max = std::max(y, y_max);
218  z_min = std::min(z, z_min);
219  z_max = std::max(z, z_max);
220  otherPoly->SetPoint(point, x, y, z);
221  ++point;
222  }
223 
224  gStyle->SetOptStat(0);
225  TH3F axes("axes", "", 1, x_min, x_max, 1, y_min, y_max, 1, z_min, z_max);
226  axes.SetDirectory(0);
227  axes.GetXaxis()->SetTitle("X");
228  axes.GetYaxis()->SetTitle("Y");
229  axes.GetZaxis()->SetTitle("Z");
230  axes.Draw();
231 
232  otherPoly->SetMarkerStyle(20);
233  otherPoly->SetMarkerColor(4);
234  otherPoly->Draw();
235 
236  // Draw all of the things
237  showerPoly->SetMarkerStyle(20);
238  showerPoly->Draw();
239  trackPoly->SetMarkerStyle(20);
240  trackPoly->SetMarkerColor(2);
241  trackPoly->Draw();
242  startPoly->SetMarkerStyle(21);
243  startPoly->SetMarkerSize(2);
244  startPoly->SetMarkerColor(3);
245  startPoly->Draw();
246  dirPoly->SetLineWidth(1);
247  dirPoly->SetLineColor(6);
248  dirPoly->Draw();
249 
250  // Save the canvas. Don't usually need this when using TFileService but this in the alg
251  // not a module and didn't work without this so im going with it.
252  canvas->Write();
253 }
254 
255 int
257  const art::Ptr<recob::Hit>& hit) const
258 {
259 
260  double particleEnergy = 0;
261  int likelyTrackID = 0;
263  std::vector<sim::TrackIDE> trackIDs = bt_serv->HitToTrackIDEs(clockData, hit);
264  for (unsigned int idIt = 0; idIt < trackIDs.size(); ++idIt) {
265  if (trackIDs.at(idIt).energy > particleEnergy) {
266  particleEnergy = trackIDs.at(idIt).energy;
267  likelyTrackID = trackIDs.at(idIt).trackID;
268  }
269  }
270  return likelyTrackID;
271 }
272 
273 std::pair<int, double>
275  detinfo::DetectorClocksData const& clockData,
276  std::map<int, std::vector<int>> const& ShowersMothers,
277  std::vector<art::Ptr<recob::Hit>> const& hits,
278  int planeid) const
279 {
280 
283 
284  //Find the energy for each track ID.
285  std::map<int, double> trackIDToEDepMap;
286  std::map<int, double> trackIDTo3EDepMap;
287  for (std::vector<art::Ptr<recob::Hit>>::const_iterator hitIt = hits.begin(); hitIt != hits.end();
288  ++hitIt) {
289  art::Ptr<recob::Hit> hit = *hitIt;
290 
291  //Get the plane ID
292  geo::WireID wireid = (*hitIt)->WireID();
293  int PlaneID = wireid.Plane;
294  std::vector<sim::TrackIDE> trackIDs = bt_serv->HitToTrackIDEs(clockData, hit);
295  for (unsigned int idIt = 0; idIt < trackIDs.size(); ++idIt) {
296  trackIDTo3EDepMap[std::abs(trackIDs[idIt].trackID)] += trackIDs[idIt].energy;
297  if (PlaneID == planeid) {
298  trackIDToEDepMap[std::abs(trackIDs[idIt].trackID)] += trackIDs[idIt].energy;
299  }
300  }
301  }
302 
303  //Find the energy for each showermother.
304  std::map<int, double> MotherIDtoEMap;
305  std::map<int, double> MotherIDto3EMap;
306  for (std::map<int, std::vector<int>>::const_iterator showermother = ShowersMothers.begin();
307  showermother != ShowersMothers.end();
308  ++showermother) {
309  for (std::vector<int>::const_iterator daughter = (showermother->second).begin();
310  daughter != (showermother->second).end();
311  ++daughter) {
312  MotherIDtoEMap[showermother->first] += trackIDToEDepMap[*daughter];
313  MotherIDto3EMap[showermother->first] += trackIDTo3EDepMap[*daughter];
314  }
315  }
316 
317  //Loop over the mothers to find the most like candidate by identifying which true shower deposited the most energy in the hits.
318  double maxenergy = -1;
319  int objectTrack = -99999;
320  for (std::map<int, double>::iterator mapIt = MotherIDto3EMap.begin();
321  mapIt != MotherIDto3EMap.end();
322  mapIt++) {
323  double energy_three = mapIt->second;
324  double trackid = mapIt->first;
325  if (energy_three > maxenergy) {
326  maxenergy = energy_three;
327  objectTrack = trackid;
328  }
329  }
330 
331  //If the none of the shower mother deposited no energy then we cannot match this.
332  if (maxenergy == 0) { return std::make_pair(-99999, -99999); }
333 
334  return std::make_pair(objectTrack, MotherIDtoEMap[objectTrack]);
335 }
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
intermediate_table::iterator iterator
int PdgCode() const
Definition: MCParticle.h:212
EventNumber_t event() const
Definition: DataViewImpl.cc:85
shower::LArPandoraShowerAlg fLArPandoraShowerAlg
size_t Self() const
Returns the index of this particle.
Definition: PFParticle.h:92
std::vector< sim::TrackIDE > HitToTrackIDEs(detinfo::DetectorClocksData const &clockData, recob::Hit const &hit) const
std::string string
Definition: nybbler.cc:12
int Mother() const
Definition: MCParticle.h:213
std::map< int, const simb::MCParticle * > GetTrueParticleMap() const
struct vector vector
STL namespace.
intermediate_table::const_iterator const_iterator
LArPandoraShowerCheatingAlg(const fhicl::ParameterSet &pset)
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
int TrackId() const
Definition: MCParticle.h:210
T abs(T value)
art::ServiceHandle< cheat::ParticleInventoryService > particleInventory
int PdgCode(Resonance_t res, int Q)
(resonance id, charge) -> PDG code
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
SubRunNumber_t subRun() const
Definition: DataViewImpl.cc:78
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
double SpacePointProjection(art::Ptr< recob::SpacePoint > const &sp, TVector3 const &vertex, TVector3 const &direction) const
RunNumber_t run() const
Definition: DataViewImpl.cc:71
static int max(int a, int b)
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 TrueParticleID(detinfo::DetectorClocksData const &clockData, const art::Ptr< recob::Hit > &hit) const
Detector simulation of raw signals on wires.
const sim::ParticleList & ParticleList() const
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
art::ServiceHandle< art::TFileService > tfs
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
Contains all timing reference information for the detector.
constexpr WireID()=default
Default constructor: an invalid TPC ID.
detail::Node< FrameID, bool > PlaneID
Definition: CRTID.h:125
list x
Definition: train.py:276
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:297
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)
Event finding and building.
TVector3 SpacePointPosition(art::Ptr< recob::SpacePoint > const &sp) const