All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Razzle_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: Razzle
3 // Plugin Type: producer (art v3_05_01)
4 // File: Razzle_module.cc
5 //
6 // Generated at Tue Jan 26 08:37:49 2021 by Edward Tyley using cetskelgen
7 // from cetlib version v3_10_00.
8 //
9 // Module that attempts to classify each shower as either:
10 // - Electron (11)
11 // - Photon (22)
12 // - Other (0)
13 //
14 // If a shower is not classified (becuase it is too small) it will be
15 // assigned a pdg of -5
16 ////////////////////////////////////////////////////////////////////////
17 
18 #include "art/Framework/Core/EDProducer.h"
19 #include "art/Framework/Core/ModuleMacros.h"
20 #include "art/Framework/Principal/DataViewImpl.h"
21 #include "art/Framework/Principal/Event.h"
22 #include "art/Framework/Principal/Handle.h"
23 #include "art/Framework/Principal/Run.h"
24 #include "art/Framework/Principal/SubRun.h"
25 #include "art_root_io/TFileService.h"
26 #include "canvas/Persistency/Common/FindManyP.h"
27 #include "canvas/Persistency/Common/Ptr.h"
28 #include "canvas/Persistency/Common/PtrVector.h"
29 #include "canvas/Utilities/InputTag.h"
30 #include "fhiclcpp/ParameterSet.h"
32 #include "messagefacility/MessageLogger/MessageLogger.h"
33 
47 
50 
51 // Root Includes
52 #include "TCanvas.h"
53 #include "TF1.h"
54 #include "TGraph.h"
55 #include "TH1F.h"
56 #include "TMath.h"
57 #include "TTree.h"
58 
59 #include "TMVA/MethodCuts.h"
60 #include "TMVA/Reader.h"
61 #include "TMVA/Tools.h"
62 
63 #include <iostream>
64 #include <vector>
65 #include <numeric> // std::accumulate
66 
67 namespace sbn {
68 class Razzle : public art::EDProducer {
69  public:
70  explicit Razzle(fhicl::ParameterSet const& p);
71  // The compiler-generated destructor is fine for non-base
72  // classes without bare pointers or other resource use.
73 
74  // Plugins should not be copied or assigned.
75  Razzle(Razzle const&) = delete;
76  Razzle(Razzle&&) = delete;
77  Razzle& operator=(Razzle const&) = delete;
78  Razzle& operator=(Razzle&&) = delete;
79 
80  // Required functions.
81  void produce(art::Event& e) override;
82  void beginJob() override;
83 
84  private:
85  // Declare member data here.
86  art::ServiceHandle<art::TFileService> tfs;
87  art::ServiceHandle<cheat::ParticleInventoryService> particleInventory;
88 
90  const float fMinShowerEnergy;
91  const bool fMakeTree, fRunMVA;
92  const std::string fMethodName, fWeightFile;
93 
94  // FV defintion
95  const float fXMin, fXMax, fYMin, fYMax, fZMin, fZMax;
96 
97  // The metrics actually used in the MVA
98  float bestdEdx; // The dE/dx at the start of the shower (in the best plane)
99  float convGap; // The gap between the shower start and parent vertex
100  float openAngle; // Opening Angle of the shower, defined as atan(width/length)
101  float modHitDensity; // The hit density corrected for the pitch (hits/wire)
102  // Theory says the length grows like the log of the energy but in practice the sqrt gives a flatter distribution
103  // float logEnergyDensity; // The log of the energy divided by the length
104  float sqrtEnergyDensity; // Sqrt of the energy divided by the length
105 
106  // MVA scores
108  int bestPDG;
109 
110  // Other metrics for filling in tree for analysis
111  TMVA::Reader* reader;
112  TTree* showerTree;
113 
116 
118  float trackScore;
122 
123  std::string trueType, trueEndProcess;
124 
125  void ClearTreeValues();
126  void FillTrueParticleMetrics(const detinfo::DetectorClocksData& clockData, const recob::Shower& shower, const std::vector<art::Ptr<recob::Hit>>& hits,
127  std::vector<art::Ptr<sim::SimChannel>>& simChannels);
128  void FillShowerMetrics(const recob::Shower& shower, const std::vector<art::Ptr<recob::Hit>>& hitVec);
129  void FillPFPMetrics(const art::Ptr<recob::PFParticle>& pfp, const std::map<size_t, art::Ptr<recob::PFParticle>>& pfpMap,
130  const recob::Shower& shower, const art::FindManyP<larpandoraobj::PFParticleMetadata>& fmMeta, const art::FindManyP<recob::Vertex>& fmVertex);
131  void FillDensityFitMetrics(const ShowerDensityFit& densityFit);
132  void FillTrackFitMetrics(const ShowerTrackFit& trackFit);
133  MVAPID RunMVA();
134 
135  std::map<size_t, art::Ptr<recob::PFParticle>> GetPFPMap(std::vector<art::Ptr<recob::PFParticle>>& pfps) const;
136  float GetPFPTrackScore(const art::Ptr<recob::PFParticle>& pfp, const art::FindManyP<larpandoraobj::PFParticleMetadata>& fmMeta) const;
137  bool InFV(const TVector3& pos) const;
138  std::string PdgString(const int pdg) const;
139 };
140 
141 Razzle::Razzle(fhicl::ParameterSet const& p)
142  : EDProducer { p }
143  , fSimChannelLabel(p.get<std::string>("SimChannelLabel"))
144  , fPFPLabel(p.get<std::string>("PFPLabel"))
145  , fShowerLabel(p.get<std::string>("ShowerLabel"))
146  , fShowerSelVarsLabel(p.get<std::string>("ShowerSelVarsLabel"))
147  , fMinShowerEnergy(p.get<float>("MinShowerEnergy"))
148  , fMakeTree(p.get<bool>("MakeTree"))
149  , fRunMVA(p.get<bool>("RunMVA"))
150  , fMethodName(p.get<std::string>("MethodName", ""))
151  , fWeightFile(p.get<std::string>("WeightFile", ""))
152  , fXMin(p.get<float>("XMin"))
153  , fXMax(p.get<float>("XMax"))
154  , fYMin(p.get<float>("YMin"))
155  , fYMax(p.get<float>("YMax"))
156  , fZMin(p.get<float>("ZMin"))
157  , fZMax(p.get<float>("ZMax"))
158 {
159  if (!fMakeTree && !fRunMVA)
160  throw cet::exception("Razzle") << "Configured to do nothing";
161 
162  if (fRunMVA) {
163  if (fMethodName == "" || fWeightFile == "")
164  throw cet::exception("Razzle") << "Trying to run MVA with inputs not set: MethodName: " << fMethodName << " and WeightFile: " << fWeightFile;
165 
166  cet::search_path searchPath("FW_SEARCH_PATH");
167  std::string fWeightFileFullPath;
168  if (!searchPath.find_file(fWeightFile, fWeightFileFullPath))
169  throw cet::exception("Razzle") << "Unable to find weight file: " << fWeightFile << " in FW_SEARCH_PATH: " << searchPath.to_string();
170 
171  reader = new TMVA::Reader("V");
172 
173  // reader->AddVariable("recoLen", &recoLen);
174  reader->AddVariable("bestdEdx", &bestdEdx);
175  reader->AddVariable("convGap", &convGap);
176  reader->AddVariable("openAngle", &openAngle);
177  reader->AddVariable("modHitDensity", &modHitDensity);
178  // reader->AddVariable("logEnergyDensity", &logEnergyDensity);
179  reader->AddVariable("sqrtEnergyDensity", &sqrtEnergyDensity);
180 
181  reader->BookMVA(fMethodName, fWeightFileFullPath);
182  }
183  // Call appropriate produces<>() functions here.
184  produces<std::vector<MVAPID>>();
185  produces<art::Assns<recob::Shower, MVAPID>>();
186 }
187 
189 {
190  if (fMakeTree) {
191  showerTree = tfs->make<TTree>("showerTree", "Tree filled per Shower with PID variables");
192 
193  if (fRunMVA) {
194  showerTree->Branch("electronScore", &electronScore);
195  showerTree->Branch("photonScore", &photonScore);
196  showerTree->Branch("otherScore", &otherScore);
197  showerTree->Branch("bestScore", &bestScore);
198  showerTree->Branch("bestPDG", &bestPDG);
199  }
200 
201  showerTree->Branch("truePdg", &truePdg);
202  showerTree->Branch("trueP", &trueP);
203  showerTree->Branch("trueType", &trueType);
204  showerTree->Branch("trueEndProcess", &trueEndProcess);
205  showerTree->Branch("energyComp", &energyComp);
206  showerTree->Branch("energyPurity", &energyPurity);
207 
208  showerTree->Branch("startX", &startX);
209  showerTree->Branch("startY", &startY);
210  showerTree->Branch("startZ", &startZ);
211 
212  showerTree->Branch("endX", &endX);
213  showerTree->Branch("endY", &endY);
214  showerTree->Branch("endZ", &endZ);
215 
216  showerTree->Branch("trueStartX", &trueStartX);
217  showerTree->Branch("trueStartY", &trueStartY);
218  showerTree->Branch("trueStartZ", &trueStartZ);
219 
220  showerTree->Branch("trueEndX", &trueEndX);
221  showerTree->Branch("trueEndY", &trueEndY);
222  showerTree->Branch("trueEndZ", &trueEndZ);
223 
224  showerTree->Branch("startDist", &startDist);
225  showerTree->Branch("endDist", &endDist);
226 
227  showerTree->Branch("numHits", &numHits);
228  showerTree->Branch("bestPlane", &bestPlane);
229 
230  showerTree->Branch("recoPrimary", &recoPrimary);
231  showerTree->Branch("numDaughters", &numDaughters);
232  showerTree->Branch("trackScore", &trackScore);
233  showerTree->Branch("convGap", &convGap);
234  showerTree->Branch("recoContained", &recoContained);
235 
236  showerTree->Branch("densityFitGrad", &densityFitGrad);
237  showerTree->Branch("densityFitPow", &densityFitPow);
238 
239  showerTree->Branch("trackLength", &trackLength);
240  showerTree->Branch("trackWidth", &trackWidth);
241  showerTree->Branch("trackHits", &trackHits);
242 
243  showerTree->Branch("length", &length);
244  showerTree->Branch("openAngle", &openAngle);
245  showerTree->Branch("bestdEdx", &bestdEdx);
246  showerTree->Branch("bestEnergy", &bestEnergy);
247  showerTree->Branch("bestPlaneHits", &bestPlaneHits);
248  showerTree->Branch("bestPitch", &bestPitch);
249  showerTree->Branch("modHitDensity", &modHitDensity);
250  showerTree->Branch("sqrtEnergyDensity", &sqrtEnergyDensity);
251  showerTree->Branch("logEnergyDensity", &logEnergyDensity);
252  }
253 }
254 
255 void Razzle::produce(art::Event& e)
256 {
257  auto const clockData(art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(e));
258 
259  auto const pfpHandle(e.getValidHandle<std::vector<recob::PFParticle>>(fPFPLabel));
260  auto const simChannelHandle(e.getValidHandle<std::vector<sim::SimChannel>>(fSimChannelLabel));
261  auto const showerHandle(e.getValidHandle<std::vector<recob::Shower>>(fShowerLabel));
262 
263  std::vector<art::Ptr<recob::PFParticle>> pfps;
264  art::fill_ptr_vector(pfps, pfpHandle);
265 
266  std::vector<art::Ptr<sim::SimChannel>> simChannels;
267  art::fill_ptr_vector(simChannels, simChannelHandle);
268 
269  art::FindManyP<recob::Vertex> fmPFPVertex(pfpHandle, e, fPFPLabel);
270  art::FindManyP<larpandoraobj::PFParticleMetadata> fmPFPMeta(pfpHandle, e, fPFPLabel);
271 
272  art::FindManyP<recob::Shower> fmPFPShower(pfpHandle, e, fShowerLabel);
273  art::FindManyP<recob::Hit> fmShowerHit(showerHandle, e, fShowerLabel);
274 
275  art::FindManyP<ShowerDensityFit> fmShowerDensityFit(showerHandle, e, fShowerSelVarsLabel);
276  art::FindManyP<ShowerTrackFit> fmShowerTrackFit(showerHandle, e, fShowerSelVarsLabel);
277 
278  auto mvaPIDVec = std::make_unique<std::vector<MVAPID>>();
279  auto showerAssns = std::make_unique<art::Assns<recob::Shower, MVAPID>>();
280 
281  const std::map<size_t, art::Ptr<recob::PFParticle>> pfpMap(this->GetPFPMap(pfps));
282 
283  for (auto const& pfp : pfps) {
284  this->ClearTreeValues();
285 
286  // Get the shower for the PFP
287  std::vector<art::Ptr<recob::Shower>> pfpShowerVec(fmPFPShower.at(pfp.key()));
288 
289  // Skip showers and primaries
290  if (pfpShowerVec.empty())
291  continue;
292 
293  // There should be 1-1 PFP to showers
294  if (pfpShowerVec.size() > 1)
295  throw cet::exception("Razzle") << "Too many showers: " << pfpShowerVec.size();
296 
297  art::Ptr<recob::Shower>& pfpShower(pfpShowerVec.front());
298 
299  if (pfpShower->best_plane() < 0 || pfpShower->Energy().at(pfpShower->best_plane()) < fMinShowerEnergy)
300  continue;
301 
302  std::vector<art::Ptr<recob::Hit>> showerHitVec(fmShowerHit.at(pfpShower.key()));
303 
304  this->FillShowerMetrics(*pfpShower, showerHitVec);
305 
306  this->FillPFPMetrics(pfp, pfpMap, *pfpShower, fmPFPMeta, fmPFPVertex);
307 
308  auto const densityFitVec(fmShowerDensityFit.at(pfpShower.key()));
309  if (densityFitVec.size() == 1)
310  this->FillDensityFitMetrics(*densityFitVec.front());
311 
312  auto const trackFitVec(fmShowerTrackFit.at(pfpShower.key()));
313  if (trackFitVec.size() == 1)
314  this->FillTrackFitMetrics(*trackFitVec.front());
315 
316  if (fRunMVA) {
317  MVAPID mvaPID(this->RunMVA());
318  mvaPIDVec->push_back(mvaPID);
319  util::CreateAssn(*this, e, *mvaPIDVec, pfpShower, *showerAssns);
320  }
321 
322  // Only fill the truth metrics if we are saving a TTree
323  if (fMakeTree) {
324  this->FillTrueParticleMetrics(clockData, *pfpShower, showerHitVec, simChannels);
325  showerTree->Fill();
326  }
327  }
328  e.put(std::move(mvaPIDVec));
329  e.put(std::move(showerAssns));
330 }
331 
333 {
334  truePdg = -5;
335  numHits = -5;
336  bestPlane = -5;
337 
338  recoContained = -5;
339  recoPrimary = -5;
340  numDaughters = -5;
341 
342  trackScore = -5.f;
343  convGap = -5.f;
344 
345  electronScore = -5.f;
346  photonScore = -5.f;
347  otherScore = -5.f;
348  bestScore = -5.f;
349  bestPDG = -5;
350 
351  startX = -999.f;
352  startY = -999.f;
353  startZ = -999.f;
354  endX = -999.f;
355  endY = -999.f;
356  endZ = -999.f;
357  trueStartX = -999.f;
358  trueStartY = -999.f;
359  trueStartZ = -999.f;
360  trueEndX = -999.f;
361  trueEndY = -999.f;
362  trueEndZ = -999.f;
363  startDist = -999.f;
364  endDist = -999.f;
365 
366  trueP = -5.f;
367  energyPurity = -5.f;
368  energyComp = -5.f;
369 
370  densityFitGrad = -5.f;
371  densityFitPow = -5.f;
372 
373  trackWidth = -5.f;
374  trackLength = -5.f;
375  trackHits = -5;
376 
377  length = -5.f;
378  openAngle = -5.f;
379  bestdEdx = -5.f;
380  bestEnergy = -5.f;
381  bestPlaneHits = -5.f;
382  bestPitch = -5.f;
383  modHitDensity = -5.f;
384  logEnergyDensity = -5.f;
385  sqrtEnergyDensity = -5.f;
386 
387  trueType = "";
388  trueEndProcess = "";
389 }
390 
391 void Razzle::FillTrueParticleMetrics(const detinfo::DetectorClocksData& clockData, const recob::Shower& shower, const std::vector<art::Ptr<recob::Hit>>& hits, std::vector<art::Ptr<sim::SimChannel>>& simChannels)
392 {
393  art::ServiceHandle<cheat::BackTrackerService> bt_serv;
394  const int bestMatch(TruthMatchUtils::TrueParticleIDFromTotalTrueEnergy(clockData, hits, true));
395 
396  if (!TruthMatchUtils::Valid(bestMatch))
397  return;
398 
399  float totalHitEnergy(0.f), totalTrueHitEnergy(0.f);
400  for (auto const& hit : hits) {
401  const std::vector<sim::TrackIDE> trackIDEs(bt_serv->HitToTrackIDEs(clockData, hit));
402  totalHitEnergy = std::accumulate(trackIDEs.cbegin(), trackIDEs.cend(), totalHitEnergy,
403  [](float sum, auto const& ide) { return sum + ide.energy; });
404  totalTrueHitEnergy = std::accumulate(trackIDEs.cbegin(), trackIDEs.cend(), totalTrueHitEnergy,
405  [bestMatch](float sum, auto const& ide) { return (std::abs(ide.trackID) == bestMatch) ? sum + ide.energy : sum; });
406  }
407 
408  const std::vector<const sim::IDE*> trackIDEs(bt_serv->TrackIdToSimIDEs_Ps(bestMatch));
409  float totalTrueEnergy(std::accumulate(trackIDEs.cbegin(), trackIDEs.cend(), 0.f,
410  [](float sum, auto const& ide) { return sum + ide->energy; }));
411 
412  energyComp = totalTrueHitEnergy / totalTrueEnergy;
413  energyPurity = totalTrueHitEnergy / totalHitEnergy;
414 
415  const simb::MCParticle* const trueParticle(particleInventory->TrackIdToParticle_P(bestMatch));
416 
417  if (!trueParticle)
418  return;
419 
420  truePdg = trueParticle->PdgCode();
421  trueType = this->PdgString(truePdg);
422  trueEndProcess = trueParticle->EndProcess();
423 
424  trueP = trueParticle->P();
425 
426  const TVector3 showerStart(shower.ShowerStart());
427  const TVector3 showerEnd(showerStart + shower.Length() * shower.Direction());
428 
429  // Select first traj point where the photon loses energy, last be default
430  TVector3 PositionTrajStart(trueParticle->Position(0).Vect());
431 
432  // For phoyons say the shower started when the photon loses 10% of the energy
433  if (trueParticle->PdgCode() == 22) {
434  unsigned int trajPoint(1);
435  while (trueParticle->E(trajPoint) == trueParticle->E()) {
436  trajPoint++;
437  }
438  PositionTrajStart = trueParticle->Position(trajPoint).Vect();
439  }
440 
441  const TVector3 trueStart(PositionTrajStart);
442  const TVector3 trueEnd(trueParticle->EndPosition().Vect());
443 
444  trueStartX = trueStart.X();
445  trueStartY = trueStart.Y();
446  trueStartZ = trueStart.Z();
447 
448  trueEndX = trueEnd.X();
449  trueEndY = trueEnd.Y();
450  trueEndZ = trueEnd.Z();
451 
452  startDist = (trueStart - showerStart).Mag();
453  endDist = (trueEnd - showerEnd).Mag();
454 }
455 
456 void Razzle::FillShowerMetrics(const recob::Shower& shower, const std::vector<art::Ptr<recob::Hit>>& hitVec)
457 {
458  const geo::GeometryCore* geom = lar::providerFrom<geo::Geometry>();
459 
460  length = shower.Length();
461  openAngle = shower.OpenAngle();
462 
463  const TVector3 start(shower.ShowerStart());
464  const TVector3 end(start + length * shower.Direction());
465  recoContained = this->InFV(start) && this->InFV(end);
466 
467  numHits = hitVec.size();
468 
469  std::array<int, 3> showerPlaneHits { 0, 0, 0 };
470  for (auto const& hit : hitVec) {
471  showerPlaneHits[hit->WireID().Plane]++;
472  }
473 
474  std::array<float, 3> showerPlanePitches { -1.f, -1.f, -1.f };
475  for (geo::PlaneGeo const& plane : geom->IteratePlanes()) {
476 
477  const float angleToVert(geom->WireAngleToVertical(plane.View(), plane.ID()) - 0.5 * M_PI);
478  const float cosgamma(std::abs(std::sin(angleToVert) * shower.Direction().Y() + std::cos(angleToVert) * shower.Direction().Z()));
479 
480  showerPlanePitches[plane.ID().Plane] = plane.WirePitch() / cosgamma;
481  }
482 
483  // Fill only for the best plane, defined as the one with the most hits
484  // Prefer collection plane > 1st induction > 2nd induction
485  bestPlane = shower.best_plane();
486 
487  if (bestPlane < 0 || bestPlane > 3)
488  throw cet::exception("Razzle") << "Best plane: " << bestPlane;
489 
490  bestdEdx = shower.dEdx()[bestPlane];
491  bestdEdx = std::min(bestdEdx, 20.f);
492  bestdEdx = std::max(bestdEdx, -5.f);
493 
494  bestEnergy = shower.Energy()[bestPlane];
495  bestPlaneHits = showerPlaneHits[bestPlane];
496  bestPitch = showerPlanePitches[bestPlane];
497 
498  logEnergyDensity = (length > 0 && bestEnergy > 0) ? std::log(bestEnergy) / length : -5.f;
499  sqrtEnergyDensity = (length > 0 && bestEnergy > 0) ? std::sqrt(bestEnergy) / length : -5.f;
500 
501  const float wiresHit(bestPitch > std::numeric_limits<float>::epsilon() ? length / bestPitch : -5.f);
502  modHitDensity = wiresHit > 1.f ? bestPlaneHits / wiresHit : -5.f;
503  modHitDensity = std::min(modHitDensity, 40.f);
504 
505  if (!fMakeTree)
506  return;
507 
508  startX = start.X();
509  startY = start.Y();
510  startZ = start.Z();
511 
512  endX = end.X();
513  endY = end.Y();
514  endZ = end.Z();
515 }
516 
517 bool Razzle::InFV(const TVector3& pos) const
518 {
519  return (pos.X() > fXMin && pos.X() < fXMax && pos.Y() > fYMin && pos.Y() < fYMax && pos.Z() > fZMin && pos.Z() < fZMax);
520 }
521 
522 void Razzle::FillPFPMetrics(const art::Ptr<recob::PFParticle>& pfp, const std::map<size_t, art::Ptr<recob::PFParticle>>& pfpMap,
523  const recob::Shower& shower, const art::FindManyP<larpandoraobj::PFParticleMetadata>& fmMeta, const art::FindManyP<recob::Vertex>& fmVertex)
524 {
525  numDaughters = pfp->Daughters().size();
526  trackScore = this->GetPFPTrackScore(pfp, fmMeta);
527 
528  auto const parentId(pfp->Parent());
529  auto const& parentIter(pfpMap.find(parentId));
530 
531  if (parentIter == pfpMap.end())
532  return;
533 
534  recoPrimary = parentIter->second->IsPrimary();
535 
536  auto const& parentVertexVec = fmVertex.at(parentIter->second.key());
537 
538  if (parentVertexVec.empty())
539  return;
540 
541  // Need to convert vertex to TVector3 for ease of comparison to shower start
542  const auto parentVertexPoint(parentVertexVec.front()->position());
543  const TVector3 parentVertex { parentVertexPoint.X(), parentVertexPoint.Y(), parentVertexPoint.Z() };
544 
545  convGap = (shower.ShowerStart() - parentVertex).Mag();
546  convGap = std::min(convGap, 50.f);
547 }
548 
550 {
551  densityFitGrad = densityFit.mDensityGrad;
552  densityFitPow = densityFit.mDensityPow;
553 }
555 {
556  trackLength = trackFit.mTrackLength;
557  trackWidth = trackFit.mTrackWidth;
558  trackHits = trackFit.mNumHits;
559 }
560 
562 {
563  const std::vector<float> mvaScores(reader->EvaluateMulticlass(fMethodName));
564 
565  MVAPID pidResults;
566 
567  pidResults.AddScore(11, mvaScores.at(0));
568  pidResults.AddScore(22, mvaScores.at(1));
569  pidResults.AddScore(0, mvaScores.at(2));
570 
571  if (!fMakeTree)
572  return pidResults;
573 
574  electronScore = mvaScores.at(0);
575  photonScore = mvaScores.at(1);
576  otherScore = mvaScores.at(2);
577 
578  bestScore = pidResults.BestScore();
579  bestPDG = pidResults.BestPDG();
580 
581  return pidResults;
582 }
583 
584 std::map<size_t, art::Ptr<recob::PFParticle>> Razzle::GetPFPMap(std::vector<art::Ptr<recob::PFParticle>>& pfps) const
585 {
586  std::map<size_t, art::Ptr<recob::PFParticle>> pfpMap;
587  for (auto const& pfp : pfps) {
588  pfpMap[pfp->Self()] = pfp;
589  }
590  return pfpMap;
591 }
592 
593 float Razzle::GetPFPTrackScore(const art::Ptr<recob::PFParticle>& pfp, const art::FindManyP<larpandoraobj::PFParticleMetadata>& fmMeta) const
594 {
595  auto const pfpMetaVec(fmMeta.at(pfp.key()));
596  if (pfpMetaVec.size() != 1)
597  return -5.f;
598  const larpandoraobj::PFParticleMetadata::PropertiesMap propertiesMap(pfpMetaVec.front()->GetPropertiesMap());
599  auto const& pfpTrackScoreIter = propertiesMap.find("TrackScore");
600  return pfpTrackScoreIter == propertiesMap.end() ? -5.f : pfpTrackScoreIter->second;
601 }
602 
603 std::string Razzle::PdgString(const int pdg) const
604 {
605  switch (std::abs(pdg)) {
606  case 11:
607  return "Electron";
608  case 22:
609  return "Photon";
610  default:
611  return "Other";
612  }
613 }
614 }
615 
616 DEFINE_ART_MODULE(sbn::Razzle)
float energyPurity
Utilities related to art service access.
float sqrtEnergyDensity
var pdg
Definition: selectors.fcl:14
float bestPlaneHits
const bool fRunMVA
IteratorBox< plane_iterator,&GeometryCore::begin_plane,&GeometryCore::end_plane > IteratePlanes() const
Enables ranged-for loops on all planes of the detector.
art::InputTag fSimChannelLabel
const TVector3 & Direction() const
Definition: Shower.h:189
Declaration of signal hit object.
const float fZMin
pdgs p
Definition: selectors.fcl:22
const std::vector< double > & dEdx() const
Definition: Shower.h:203
bool InFV(const TVector3 &pos) const
int best_plane() const
Definition: Shower.h:200
const float fYMin
std::map< std::string, float > PropertiesMap
const std::string fWeightFile
process_name hit
Definition: cheaterreco.fcl:51
void FillTrueParticleMetrics(const detinfo::DetectorClocksData &clockData, const recob::Shower &shower, const std::vector< art::Ptr< recob::Hit >> &hits, std::vector< art::Ptr< sim::SimChannel >> &simChannels)
void FillTrackFitMetrics(const ShowerTrackFit &trackFit)
const float fXMin
process_name shower
Definition: cheaterreco.fcl:51
art::InputTag fShowerLabel
art::InputTag fShowerSelVarsLabel
void FillShowerMetrics(const recob::Shower &shower, const std::vector< art::Ptr< recob::Hit >> &hitVec)
double Length() const
Definition: Shower.h:201
const std::string fMethodName
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
T abs(T value)
Razzle(fhicl::ParameterSet const &p)
art::InputTag fPFPLabel
Utilities for matching a recob::Hit or vector of recob::Hit to the ID of the most significantly contr...
double OpenAngle() const
Definition: Shower.h:202
void beginJob() override
std::string trueEndProcess
art::ServiceHandle< cheat::ParticleInventoryService > particleInventory
Geometry information for a single wire plane.The plane is represented in the geometry by a solid whic...
Definition: PlaneGeo.h:82
std::string trueType
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
const bool fMakeTree
std::string PdgString(const int pdg) const
Description of geometry of one entire detector.
void ClearTreeValues()
bool Valid(const G4ID g4ID) noexcept
Test whether a G4ID returned by the TruthMatchUtils functions is valid.
bool CreateAssn(art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t index=UINT_MAX)
Creates a single one-to-one association.
float densityFitGrad
float modHitDensity
std::map< size_t, art::Ptr< recob::PFParticle > > GetPFPMap(std::vector< art::Ptr< recob::PFParticle >> &pfps) const
const float fZMax
void FillDensityFitMetrics(const ShowerDensityFit &densityFit)
float densityFitPow
const float fMinShowerEnergy
void FillPFPMetrics(const art::Ptr< recob::PFParticle > &pfp, const std::map< size_t, art::Ptr< recob::PFParticle >> &pfpMap, const recob::Shower &shower, const art::FindManyP< larpandoraobj::PFParticleMetadata > &fmMeta, const art::FindManyP< recob::Vertex > &fmVertex)
Contains all timing reference information for the detector.
MVAPID RunMVA()
Razzle & operator=(Razzle const &)=delete
void produce(art::Event &e) override
G4ID TrueParticleIDFromTotalTrueEnergy(detinfo::DetectorClocksData const &clockData, const std::vector< art::Ptr< recob::Hit >> &pHits, const bool rollupUnsavedIDs)
The G4 ID of the true particle which deposits the most energy in a vector of recob::Hit.
const std::vector< double > & Energy() const
Definition: Shower.h:195
const float fYMax
do i e
const TVector3 & ShowerStart() const
Definition: Shower.h:192
TMVA::Reader * reader
art::ServiceHandle< art::TFileService > tfs
float electronScore
TTree * showerTree
float GetPFPTrackScore(const art::Ptr< recob::PFParticle > &pfp, const art::FindManyP< larpandoraobj::PFParticleMetadata > &fmMeta) const
const float fXMax
double WireAngleToVertical(geo::View_t view, geo::TPCID const &tpcid) const
Returns the angle of the wires in the specified view from vertical.
art framework interface to geometry description
float logEnergyDensity