All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NuVertexChargeTree_module.cc
Go to the documentation of this file.
1 /**
2  * @file NuVertexChargeTree_module.cc
3  * @author Gray Putnam (grayputnam@uchicago.edu)
4  */
5 
6 #include "art/Framework/Core/EDAnalyzer.h"
7 #include "art/Framework/Core/ModuleMacros.h"
8 #include "art/Framework/Principal/Event.h"
9 #include "art/Framework/Principal/Handle.h"
10 #include "art/Framework/Principal/Run.h"
11 #include "art/Framework/Principal/SubRun.h"
12 #include "canvas/Utilities/InputTag.h"
13 #include "fhiclcpp/ParameterSet.h"
14 #include "messagefacility/MessageLogger/MessageLogger.h"
15 
16 #include "art_root_io/TFileService.h"
17 
27 #include "nusimdata/SimulationBase/MCParticle.h"
40 #include "../LArRecoProducer/LArReco/TrackMomentumCalculator.h"
41 
43 
46 
47 namespace sbn {
48  class NuVertexChargeTree;
49 }
50 
51 /**
52  * @brief Analyzer module for use with sbn::Stub and sbn::VertexHit objects.
53  *
54  * Intended for use with neutrino interactions and neutrino-like particlegun
55  * events. Not intended for use on data or on MC with cosmics.
56  */
57 class sbn::NuVertexChargeTree : public art::EDAnalyzer {
58 public:
59  explicit NuVertexChargeTree(fhicl::ParameterSet const& p);
60  // The compiler-generated destructor is fine for non-base
61  // classes without bare pointers or other resource use.
62 
63  // Plugins should not be copied or assigned.
64  NuVertexChargeTree(NuVertexChargeTree const&) = delete;
68 
69  // Required functions.
70  void analyze(art::Event const& e) override;
71 
72  // keep track of file index
73  void respondToOpenInputFile(const art::FileBlock& fb) override {
74  (void) fb;
75  fIFile += 1;
76  }
77 
78 private:
79  // helpers
80  void Clear();
81  bool InFV(TVector3 pos);
82  void FillMeta(const art::Event &evt);
83  void FillNeutrino(const simb::MCTruth &nu,
84  const recob::Vertex &vert,
85  const std::vector<art::Ptr<recob::PFParticle>> &slice_pfps,
86  const std::vector<std::vector<std::pair<int, float>>> &slice_pfp_matches,
87  const std::vector<art::Ptr<simb::MCParticle>> &g4_mcparticles,
88  const std::vector<const sim::GeneratedParticleInfo *> &infos,
89  const geo::GeometryCore &geo,
90  const detinfo::DetectorPropertiesData &dprop);
91 
92  void FillVertexHits(
93  const std::vector<art::Ptr<sbn::VertexHit>> &hits,
94  const std::vector<art::Ptr<recob::Hit>> &hit_hits,
96  const detinfo::DetectorClocksData &clock_data,
97  const std::vector<art::Ptr<simb::MCParticle>> &trueParticles);
98 
99  void FillStubs(
100  const std::vector<sbn::StubInfo> &stubs,
101  const std::vector<unsigned> &stub_hit_inds,
102  const geo::GeometryCore *geo,
103  const detinfo::DetectorPropertiesData &dprop,
104  const detinfo::DetectorClocksData &clock_data,
105  const std::vector<art::Ptr<simb::MCParticle>> &trueParticles);
106 
107  void FillStubPFPs(
108  const std::vector<art::Ptr<recob::PFParticle>> &stub_pfps,
109  const std::vector<std::vector<art::Ptr<recob::Hit>>> &stub_pfp_hits,
110  const detinfo::DetectorClocksData &clock_data,
111  const std::vector<art::Ptr<simb::MCParticle>> &trueParticles);
112 
113  void FillSlice(const std::vector<art::Ptr<recob::PFParticle>> &slice_particles);
114 
115  // config
116  std::vector<std::string> fPFParticleTags;
117  std::vector<std::string> fVertexHitTags;
118  std::vector<std::string> fStubTags;
119  std::array<float, 6> fFiducialInset;
120  std::vector<geo::BoxBoundedGeo> fFiducialVolumes;
121  std::vector<std::vector<geo::BoxBoundedGeo>> fTPCVolumes;
124 
125  // output
126  TTree *_tree;
127 
128  int fIEvt;
129  int fIFile;
130  int fEvt;
131 
132  float fNuE;
133  int fNuMode;
135 
136  std::vector<float> fFSPPx;
137  std::vector<float> fFSPPy;
138  std::vector<float> fFSPPz;
139 
140  std::vector<float> fFSPE;
141  std::vector<float> fFSPQ;
142  std::vector<float> fFSPKE;
143  std::vector<float> fFSPVisE;
144  std::vector<float> fFSPLen;
145  std::vector<int> fFSPPID;
146  std::vector<bool> fFSPMatched;
147  std::vector<int> fFSPMatchedPID;
148  std::vector<bool> fFSPMatchedPFPPrimary;
149  std::vector<bool> fFSPMtachedPrimary;
150  std::vector<bool> fFSPIsStopping;
151 
152  std::vector<float> fFSPStartX;
153  std::vector<float> fFSPStartY;
154  std::vector<float> fFSPStartZ;
155  std::vector<float> fFSPEndX;
156  std::vector<float> fFSPEndY;
157  std::vector<float> fFSPEndZ;
158 
159  std::vector<float> fFSPMaxQ0;
160  std::vector<float> fFSPMaxQ1;
161  std::vector<float> fFSPMaxQ2;
162  std::vector<float> fFSPPitch0;
163  std::vector<float> fFSPPitch1;
164  std::vector<float> fFSPPitch2;
165 
167 
168  std::vector<int> fVertexHitSPID;
169  std::vector<float> fVertexHitPitch;
170  std::vector<float> fVertexHitdQdx;
171  std::vector<float> fVertexHitdEdx;
172  std::vector<float> fVertexHitCharge;
173  std::vector<float> fVertexHitDist;
174  std::vector<float> fVertexHitVtxW;
175  std::vector<int> fVertexHitPlane;
176  std::vector<int> fVertexHitWire;
177  std::vector<float> fVertexHitPeakX;
178  std::vector<float> fVertexHitTrueEnergy;
179  std::vector<float> fVertexHitTrueProtonEnergy;
181  std::vector<float> fVertexHitTrueX;
182  std::vector<float> fVertexHitTrueY;
183  std::vector<float> fVertexHitTrueZ;
184 
185  std::vector<float> fStubEndx;
186  std::vector<float> fStubEndy;
187  std::vector<float> fStubEndz;
188  std::vector<float> fStubDirx;
189  std::vector<float> fStubDiry;
190  std::vector<float> fStubDirz;
191  std::vector<float> fStubLength;
192  std::vector<float> fStubCharge;
193  std::vector<float> fStubPitch;
194  std::vector<float> fStubTrkPitch;
195  std::vector<float> fStubLenP;
196  std::vector<int> fStubNWire;
197  std::vector<int> fStubHitInd;
198  std::vector<int> fStubPFPID;
199  std::vector<int> fStubNPlane;
200  std::vector<float> fStubVtxW;
201  std::vector<int> fStubEndW;
202  std::vector<float> fStubVtxEField;
203  std::vector<float> fStubEndEField;
204 
205  std::vector<int> fStubQLength;
206  std::vector<float> fStubQs;
207  std::vector<int> fStubOnTracks;
208  std::vector<int> fStubWires;
209 
210  std::vector<float> fStubTrueKE;
211  std::vector<float> fStubTrueLength;
212  std::vector<int> fStubTrueID;
213 
214  std::vector<int> fStubTruePdg;
215  std::vector<float> fStubTruePx;
216  std::vector<float> fStubTruePy;
217  std::vector<float> fStubTruePz;
218 
219  std::vector<int> fStubPFPTruePdg;
220  std::vector<float> fStubPFPTruePx;
221  std::vector<float> fStubPFPTruePy;
222  std::vector<float> fStubPFPTruePz;
223 
224  std::vector<int> fStubMatchLength;
225  std::vector<int> fStubMatch;
226  std::vector<int> fStubMatchOverlaps;
227  std::vector<float> fStubMatchDot;
228 
229  std::vector<int> fStubXPlaneMatchLength;
230  std::vector<int> fStubXPlaneMatch;
231  std::vector<float> fStubXPlaneMatchTOff;
232  std::vector<float> fStubXPlaneMatchQOff;
233  std::vector<float> fStubXPlaneMatchdQdxOff;
234  std::vector<float> fStubXPlaneMatchPeakQOff;
235 
241 };
242 
244  : EDAnalyzer{p}, // ,
245  fPFParticleTags(p.get<std::vector<std::string>>("ParticleTags")),
246  fVertexHitTags(p.get<std::vector<std::string>>("VertexHitTags")),
247  fStubTags(p.get<std::vector<std::string>>("StubTags")),
248  fFiducialInset({p.get<float>("xmin"), p.get<float>("xmax"), p.get<float>("ymin"), p.get<float>("ymax"), p.get<float>("zmin"), p.get<float>("zmax")}),
249  fRangeCalculator(p.get<float>("MinTrackLength", 0.1)),
250  fCorrectSCE(p.get<bool>("CorrectSCE"))
251 {
252  fIEvt = 0;
253  fIFile = 0;
254  art::ServiceHandle<art::TFileService> tfs;
255 
256  _tree = tfs->make<TTree>("VertexEAnalyzer", "kink_tree");
257 
258  _tree->Branch("ifile", &fIFile, "ifile/i");
259  _tree->Branch("ievt", &fIEvt, "ievt/i");
260  _tree->Branch("evt", &fEvt, "evt/i");
261 
262  _tree->Branch("nue", &fNuE, "nue/F");
263  _tree->Branch("numode", &fNuMode, "numode/i");
264  _tree->Branch("nuinttype", &fNuIntType, "nuinttype/i");
265 
266  _tree->Branch("fsp_px", &fFSPPx);
267  _tree->Branch("fsp_py", &fFSPPy);
268  _tree->Branch("fsp_pz", &fFSPPz);
269 
270  _tree->Branch("fsp_start_x", &fFSPStartZ);
271  _tree->Branch("fsp_start_y", &fFSPStartY);
272  _tree->Branch("fsp_start_z", &fFSPStartZ);
273  _tree->Branch("fsp_end_x", &fFSPEndZ);
274  _tree->Branch("fsp_end_y", &fFSPEndY);
275  _tree->Branch("fsp_end_z", &fFSPEndZ);
276 
277  _tree->Branch("fsp_e", &fFSPE);
278  _tree->Branch("fsp_ke", &fFSPKE);
279  _tree->Branch("fsp_vise", &fFSPVisE);
280  _tree->Branch("fsp_q", &fFSPQ);
281  _tree->Branch("fsp_len", &fFSPLen);
282  _tree->Branch("fsp_pid", &fFSPPID);
283  _tree->Branch("fsp_matched", &fFSPMatched);
284  _tree->Branch("fsp_matched_pfp_primary", &fFSPMatchedPFPPrimary);
285  _tree->Branch("fsp_matched_pid", &fFSPMatchedPID);
286  _tree->Branch("fsp_matched_primary", &fFSPMtachedPrimary);
287  _tree->Branch("fsp_process_is_topping", &fFSPIsStopping);
288 
289  _tree->Branch("fsp_maxq0", &fFSPMaxQ0);
290  _tree->Branch("fsp_maxq1", &fFSPMaxQ1);
291  _tree->Branch("fsp_maxq2", &fFSPMaxQ2);
292  _tree->Branch("fsp_pitch0", &fFSPPitch0);
293  _tree->Branch("fsp_pitch1", &fFSPPitch1);
294  _tree->Branch("fsp_pitch2", &fFSPPitch2);
295 
296  _tree->Branch("reco_vert_dist", &fRecoVertDist, "reco_vert_dist/F");
297 
298  _tree->Branch("vertex_hit_spid", &fVertexHitSPID);
299  _tree->Branch("vertex_hit_pitch", &fVertexHitPitch);
300  _tree->Branch("vertex_hit_dqdx", &fVertexHitdQdx);
301  _tree->Branch("vertex_hit_dedx", &fVertexHitdEdx);
302  _tree->Branch("vertex_hit_charge", &fVertexHitCharge);
303  _tree->Branch("vertex_hit_dist", &fVertexHitDist);
304  _tree->Branch("vertex_hit_vtxw", &fVertexHitVtxW);
305  _tree->Branch("vertex_hit_plane", &fVertexHitPlane);
306  _tree->Branch("vertex_hit_wire", &fVertexHitWire);
307  _tree->Branch("vertex_hit_peak_x", &fVertexHitPeakX);
308  _tree->Branch("vertex_hit_true_e", &fVertexHitTrueEnergy);
309  _tree->Branch("vertex_hit_true_proton_e", &fVertexHitTrueProtonEnergy);
310  _tree->Branch("vertex_hit_true_bragg_proton_e", &fVertexHitTrueBraggProtonEnergy);
311  _tree->Branch("vertex_hit_true_x", &fVertexHitTrueX);
312  _tree->Branch("vertex_hit_true_y", &fVertexHitTrueY);
313  _tree->Branch("vertex_hit_true_z", &fVertexHitTrueZ);
314 
315  _tree->Branch("stub_endx", &fStubEndx);
316  _tree->Branch("stub_endy", &fStubEndy);
317  _tree->Branch("stub_endz", &fStubEndz);
318 
319  _tree->Branch("stub_dirx", &fStubDirx);
320  _tree->Branch("stub_diry", &fStubDiry);
321  _tree->Branch("stub_dirz", &fStubDirz);
322  _tree->Branch("stub_length", &fStubLength);
323  _tree->Branch("stub_lenp", &fStubLenP);
324  _tree->Branch("stub_charge", &fStubCharge);
325  _tree->Branch("stub_trk_pitch", &fStubTrkPitch);
326  _tree->Branch("stub_pitch", &fStubPitch);
327  _tree->Branch("stub_nwire", &fStubNWire);
328  _tree->Branch("stub_hit_ind", &fStubHitInd);
329  _tree->Branch("stub_pfpid", &fStubPFPID);
330  _tree->Branch("stub_nplane", &fStubNPlane);
331  _tree->Branch("stub_vtx_w", &fStubVtxW);
332  _tree->Branch("stub_end_w", &fStubEndW);
333  _tree->Branch("stub_vtx_efield", &fStubVtxEField);
334  _tree->Branch("stub_end_efield", &fStubEndEField);
335 
336  _tree->Branch("stub_qlength", &fStubQLength);
337  _tree->Branch("stub_qs", &fStubQs);
338  _tree->Branch("stub_ontracks", &fStubOnTracks);
339  _tree->Branch("stub_wires", &fStubWires);
340 
341  _tree->Branch("stub_true_ke", &fStubTrueKE);
342  _tree->Branch("stub_true_length", &fStubTrueLength);
343  _tree->Branch("stub_true_id", &fStubTrueID);
344 
345  _tree->Branch("stub_true_pdg", &fStubTruePdg);
346  _tree->Branch("stub_true_px", &fStubTruePx);
347  _tree->Branch("stub_true_py", &fStubTruePy);
348  _tree->Branch("stub_true_pz", &fStubTruePz);
349 
350  _tree->Branch("stub_pfp_true_pdg", &fStubPFPTruePdg);
351  _tree->Branch("stub_pfp_true_px", &fStubPFPTruePx);
352  _tree->Branch("stub_pfp_true_py", &fStubPFPTruePy);
353  _tree->Branch("stub_pfp_true_pz", &fStubPFPTruePz);
354 
355  _tree->Branch("stub_match_length", &fStubMatchLength);
356  _tree->Branch("stub_match", &fStubMatch);
357  _tree->Branch("stub_match_overlaps", &fStubMatchOverlaps);
358  _tree->Branch("stub_match_dot", &fStubMatchDot);
359 
360  _tree->Branch("stub_xplane_match_length", &fStubXPlaneMatchLength);
361  _tree->Branch("stub_xplane_match", &fStubXPlaneMatch);
362  _tree->Branch("stub_xplane_match_toff", &fStubXPlaneMatchTOff);
363  _tree->Branch("stub_xplane_match_qoff", &fStubXPlaneMatchQOff);
364  _tree->Branch("stub_xplane_match_dqdxoff", &fStubXPlaneMatchdQdxOff);
365  _tree->Branch("stub_xplane_match_peakqoff", &fStubXPlaneMatchPeakQOff);
366 
367  _tree->Branch("n_slice_particles", &fNSliceParticles, "n_slice_particles/i");
368  _tree->Branch("n_slice_primary_particles", &fNSlicePrimaryParticles, "n_slice_primary_particles/i");
369  _tree->Branch("n_slice_primary_tracks", &fNSlicePrimaryTracks, "n_slice_primary_tracks/i");
370  _tree->Branch("n_slice_primary_nus", &fNSlicePrimaryNus, "n_slice_primary_nus/i");
371  _tree->Branch("n_slice_primary_showers", &fNSlicePrimaryShowers, "n_slice_primary_showers/i");
372 
373  const geo::GeometryCore *geometry = lar::providerFrom<geo::Geometry>();
374 
375  // first the TPC volumes
376  for (auto const &cryo: geometry->IterateCryostats()) {
377  geo::GeometryCore::TPC_iterator iTPC = geometry->begin_TPC(cryo.ID()),
378  tend = geometry->end_TPC(cryo.ID());
379  std::vector<geo::BoxBoundedGeo> this_tpc_volumes;
380  while (iTPC != tend) {
381  geo::TPCGeo const& TPC = *iTPC;
382  this_tpc_volumes.push_back(TPC.ActiveBoundingBox());
383  iTPC++;
384  }
385  fTPCVolumes.push_back(std::move(this_tpc_volumes));
386  }
387 
388  // then combine them into active volumes
389  for (const std::vector<geo::BoxBoundedGeo> &tpcs: fTPCVolumes) {
390  double XMin = std::min_element(tpcs.begin(), tpcs.end(), [](auto &lhs, auto &rhs) { return lhs.MinX() < rhs.MinX(); })->MinX();
391  double YMin = std::min_element(tpcs.begin(), tpcs.end(), [](auto &lhs, auto &rhs) { return lhs.MinY() < rhs.MinY(); })->MinY();
392  double ZMin = std::min_element(tpcs.begin(), tpcs.end(), [](auto &lhs, auto &rhs) { return lhs.MinZ() < rhs.MinZ(); })->MinZ();
393 
394  double XMax = std::max_element(tpcs.begin(), tpcs.end(), [](auto &lhs, auto &rhs) { return lhs.MaxX() < rhs.MaxX(); })->MaxX();
395  double YMax = std::max_element(tpcs.begin(), tpcs.end(), [](auto &lhs, auto &rhs) { return lhs.MaxY() < rhs.MaxY(); })->MaxY();
396  double ZMax = std::max_element(tpcs.begin(), tpcs.end(), [](auto &lhs, auto &rhs) { return lhs.MaxZ() < rhs.MaxZ(); })->MaxZ();
397 
398  // fActiveVolumes.emplace_back(XMin, XMax, YMin, YMax, ZMin, ZMax);
399  fFiducialVolumes.emplace_back(XMin + fFiducialInset[0], XMax - fFiducialInset[1],
400  YMin + fFiducialInset[2], YMax - fFiducialInset[3],
401  ZMin + fFiducialInset[4], ZMax - fFiducialInset[5]);
402  }
403 }
404 
405 bool sbn::NuVertexChargeTree::InFV(TVector3 pos) {
406  for (auto const &FV: fFiducialVolumes) {
407  if (FV.ContainsPosition(pos)) return true;
408  }
409  return false;
410 }
411 
412 const simb::MCParticle *Genie2G4MCParticle(
413  const simb::MCParticle &genie_part,
414  const simb::MCTruth &mctruth,
415  const std::vector<art::Ptr<simb::MCParticle>> &g4_mcparticles,
416  const std::vector<const sim::GeneratedParticleInfo *> infos) {
417 
418  const simb::MCParticle *ret = nullptr;
419  for (int iparticle = 0; iparticle < (int)g4_mcparticles.size(); iparticle++) {
420  if (infos[iparticle]->hasGeneratedParticleIndex() &&
421  (int)infos[iparticle]->generatedParticleIndex() < mctruth.NParticles() && // TODO: why is this number sometimes bigger than the number of particles?
422  mctruth.GetParticle(infos[iparticle]->generatedParticleIndex()).TrackId() == genie_part.TrackId() &&
423  g4_mcparticles[iparticle]->Process() == "primary" /* TODO: will have to remove this restriction to include secondary particles*/) {
424 
425  // if a genie particle re-scatters in g4 and makes more particles, then multiple g4 particles can match to a
426  // genie particle. Thus, we also check that the start location of the associated genie particle matches the g4
427  // and that the pdgid matches (to be on the safe side)
428  //
429  // Note that this should be accounted for by requiring the process to be primary. This is a bit of redundancy.
430  const simb::MCParticle& matched_genie_particle = mctruth.GetParticle(infos[iparticle]->generatedParticleIndex());
431  if ((matched_genie_particle.Position().Vect() - g4_mcparticles[iparticle]->Position().Vect()).Mag() < 1e-4 &&
432  matched_genie_particle.PdgCode() == g4_mcparticles[iparticle]->PdgCode()) {
433 
434  // this should only be true for one particle
435  assert(ret == nullptr);
436  ret = g4_mcparticles[iparticle].get();
437  }
438  }
439  }
440  return ret;
441 }
442 
444  fEvt = 0;
445 
446  fNuE = 0;
447  fNuMode = -1;
448  fNuIntType = -1;
449 
450  fFSPPx.clear();
451  fFSPPy.clear();
452  fFSPPz.clear();
453 
454  fFSPStartX.clear();
455  fFSPStartY.clear();
456  fFSPStartZ.clear();
457  fFSPEndX.clear();
458  fFSPEndY.clear();
459  fFSPEndZ.clear();
460 
461  fFSPQ.clear();
462  fFSPE.clear();
463  fFSPKE.clear();
464  fFSPVisE.clear();
465  fFSPLen.clear();
466  fFSPPID.clear();
467  fFSPMatched.clear();
468  fFSPMatchedPFPPrimary.clear();
469  fFSPMatchedPID.clear();
470  fFSPMtachedPrimary.clear();
471  fFSPIsStopping.clear();
472 
473  fFSPMaxQ0.clear();
474  fFSPMaxQ1.clear();
475  fFSPMaxQ2.clear();
476  fFSPPitch0.clear();
477  fFSPPitch1.clear();
478  fFSPPitch2.clear();
479 
480  fRecoVertDist = 0.;
481  fVertexHitSPID.clear();
482  fVertexHitPitch.clear();
483  fVertexHitdQdx.clear();
484  fVertexHitdEdx.clear();
485  fVertexHitCharge.clear();
486  fVertexHitDist.clear();
487  fVertexHitVtxW.clear();
488  fVertexHitPlane.clear();
489  fVertexHitWire.clear();
490  fVertexHitPeakX.clear();
491  fVertexHitTrueEnergy.clear();
492  fVertexHitTrueProtonEnergy.clear();
493  fVertexHitTrueBraggProtonEnergy.clear();
494  fVertexHitTrueX.clear();
495  fVertexHitTrueY.clear();
496  fVertexHitTrueZ.clear();
497 
498  fStubEndx.clear();
499  fStubEndy.clear();
500  fStubEndz.clear();
501  fStubDirx.clear();
502  fStubDiry.clear();
503  fStubDirz.clear();
504  fStubLength.clear();
505  fStubLenP.clear();
506  fStubCharge.clear();
507  fStubTrkPitch.clear();
508  fStubPitch.clear();
509  fStubNWire.clear();
510  fStubHitInd.clear();
511  fStubPFPID.clear();
512  fStubNPlane.clear();
513  fStubVtxW.clear();
514  fStubEndW.clear();
515  fStubVtxEField.clear();
516  fStubEndEField.clear();
517 
518  fStubQLength.clear();
519  fStubQs.clear();
520  fStubOnTracks.clear();
521  fStubWires.clear();
522 
523  fStubTrueKE.clear();
524  fStubTrueLength.clear();
525  fStubTrueID.clear();
526  fStubTruePdg.clear();
527  fStubTruePx.clear();
528  fStubTruePy.clear();
529  fStubTruePz.clear();
530  fStubPFPTruePdg.clear();
531  fStubPFPTruePx.clear();
532  fStubPFPTruePy.clear();
533  fStubPFPTruePz.clear();
534 
535  fStubMatchLength.clear();
536  fStubMatch.clear();
537  fStubMatchOverlaps.clear();
538  fStubMatchDot.clear();
539 
540  fStubXPlaneMatchLength.clear();
541  fStubXPlaneMatch.clear();
542  fStubXPlaneMatchTOff.clear();
543  fStubXPlaneMatchQOff.clear();
544  fStubXPlaneMatchdQdxOff.clear();
545  fStubXPlaneMatchPeakQOff.clear();
546 
547  fNSliceParticles = 0;
548  fNSlicePrimaryParticles = 0;
549  fNSlicePrimaryTracks = 0;
550  fNSlicePrimaryNus = 0;
551  fNSlicePrimaryShowers = 0;
552 }
553 
554 void sbn::NuVertexChargeTree::FillMeta(const art::Event &evt) {
555  fEvt = evt.event();
556  fIEvt += 1;
557 }
558 
559 void sbn::NuVertexChargeTree::FillSlice(const std::vector<art::Ptr<recob::PFParticle>> &slice_particles) {
560  fNSliceParticles = slice_particles.size();
561  for (unsigned i = 0; i < slice_particles.size(); i++) {
562  bool is_primary = slice_particles[i]->IsPrimary();
563  if (!is_primary) {
564  int parent = slice_particles[i]->Parent();
565  for (unsigned j = 0; j < slice_particles.size(); j++) {
566  if ((int)slice_particles[j]->Self() == parent) {
567  is_primary = slice_particles[j]->IsPrimary() && lar_pandora::LArPandoraHelper::IsNeutrino(slice_particles[j]);
568  break;
569  }
570  }
571  }
572  if (is_primary) {
573  fNSlicePrimaryParticles ++;
574  }
575 
576  if (is_primary && lar_pandora::LArPandoraHelper::IsTrack(slice_particles[i])) {
577  fNSlicePrimaryTracks ++;
578  }
579  else if (is_primary && lar_pandora::LArPandoraHelper::IsShower(slice_particles[i])) {
580  fNSlicePrimaryShowers ++;
581  }
582  else if (is_primary && lar_pandora::LArPandoraHelper::IsNeutrino(slice_particles[i])) {
583  fNSlicePrimaryNus ++;
584  }
585 
586  }
587 }
588 
590  const std::vector<art::Ptr<recob::PFParticle>> &stub_pfps,
591  const std::vector<std::vector<art::Ptr<recob::Hit>>> &stub_pfp_hits,
592  const detinfo::DetectorClocksData &clock_data,
593  const std::vector<art::Ptr<simb::MCParticle>> &trueParticles) {
594 
595  for (unsigned i_stub = 0; i_stub < stub_pfps.size(); i_stub++) {
596  // fill PFP info
597  if (stub_pfps[i_stub]) {
598  fStubPFPID.push_back(stub_pfps[i_stub]->Self());
599  }
600  else {
601  fStubPFPID.push_back(-1);
602  }
603 
604  // truth-matching
605  std::vector<std::pair<int, float>> matches = CAFRecoUtils::AllTrueParticleIDEnergyMatches(clock_data, stub_pfp_hits[i_stub]);
606  // sort
607  std::sort(matches.begin(), matches.end(),
608  [](auto const &lhs, auto const &rhs) {
609  return lhs.second > rhs.second;
610  });
611 
612  // get the matched particle
613  art::Ptr<simb::MCParticle> G4;
614  int matched_track_id = matches.size() ? abs(matches[0].first) : -1;
615  for (unsigned i_g4 = 0; i_g4 < trueParticles.size(); i_g4++) {
616  if (matched_track_id == trueParticles[i_g4]->TrackId()) {
617  G4 = trueParticles[i_g4];
618  break;
619  }
620  }
621 
622  if (G4) {
623  fStubPFPTruePdg.push_back(G4->PdgCode());
624  fStubPFPTruePx.push_back(G4->Momentum().Px());
625  fStubPFPTruePy.push_back(G4->Momentum().Py());
626  fStubPFPTruePz.push_back(G4->Momentum().Pz());
627  }
628  else {
629  fStubPFPTruePdg.push_back(-1);
630  fStubPFPTruePx.push_back(-1);
631  fStubPFPTruePy.push_back(-1);
632  fStubPFPTruePz.push_back(-1);
633  }
634 
635  } // end iterate over Stub-PFParticle's
636 }
637 
639  const std::vector<sbn::StubInfo> &stubs,
640  const std::vector<unsigned> &stub_hit_inds,
641  const geo::GeometryCore *geo,
642  const detinfo::DetectorPropertiesData &dprop,
643  const detinfo::DetectorClocksData &clock_data,
644  const std::vector<art::Ptr<simb::MCParticle>> &trueParticles) {
645 
646  // TODO: fix -- for now, use a null space-charge service
647  const spacecharge::SpaceCharge *sce = lar::providerFrom<spacecharge::SpaceChargeService>();
648 
649  for (unsigned i_stub = 0; i_stub < stubs.size(); i_stub++) {
650  const sbn::Stub &stub = stubs[i_stub].stub;
651 
652  // fill reco info
653  fStubLength.push_back((stub.vtx - stub.end).r());
654  fStubEndx.push_back(stub.end.X());
655  fStubEndy.push_back(stub.end.Y());
656  fStubEndz.push_back(stub.end.Z());
657 
658  fStubDirx.push_back((stub.end - stub.vtx).Unit().X());
659  fStubDiry.push_back((stub.end - stub.vtx).Unit().Y());
660  fStubDirz.push_back((stub.end - stub.vtx).Unit().Z());
661  fStubNWire.push_back(stub.CoreNHit());
662  fStubTrkPitch.push_back(stub.trkpitch.front());
663  fStubPitch.push_back(stub.pitch.front());
664  fStubLenP.push_back(fRangeCalculator.GetTrackMomentum((stub.vtx - stub.end).r(), 2212));
665 
666  // Only count charge on the main stub
667  fStubCharge.push_back(stub.CoreCharge());
668 
669  // Compute per-charge stuff
670  // Save per-charge stuff
671  fStubQLength.push_back(stub.hits.front().size());
672  for (const sbn::StubHit &h: stub.hits.front()) {
673  fStubQs.push_back(h.charge);
674  fStubOnTracks.push_back(h.ontrack);
675  fStubWires.push_back(h.wire);
676  }
677 
678  fStubHitInd.push_back(stub_hit_inds[i_stub]);
679  fStubNPlane.push_back(stub.plane.size());
680  fStubVtxW.push_back(stub.vtx_w.front());
681  fStubEndW.push_back(stub.hit_w.front());
682 
683  fStubVtxEField.push_back(stub.efield_vtx);
684  fStubEndEField.push_back(stub.efield_end);
685 
686  // truth-matching
687  std::vector<std::pair<int, float>> matches = CAFRecoUtils::AllTrueParticleIDEnergyMatches(clock_data, stubs[i_stub].hits);
688  // sort
689  std::sort(matches.begin(), matches.end(),
690  [](auto const &lhs, auto const &rhs) {
691  return lhs.second > rhs.second;
692  });
693 
694  // get the matched particle
695  art::Ptr<simb::MCParticle> G4;
696  int matched_track_id = matches.size() ? abs(matches[0].first) : -1;
697  for (unsigned i_g4 = 0; i_g4 < trueParticles.size(); i_g4++) {
698  if (matched_track_id == trueParticles[i_g4]->TrackId()) {
699  G4 = trueParticles[i_g4];
700  break;
701  }
702  }
703 
704  // Fill in truth information
705  if (G4) {
706  fStubTruePdg.push_back(G4->PdgCode());
707  fStubTrueID.push_back(G4->TrackId());
708  fStubTrueKE.push_back(G4->Momentum().E() - G4->Momentum().M());
709  fStubTrueLength.push_back((G4->Position().Vect() - G4->EndPosition().Vect()).Mag());
710 
711  fStubTruePx.push_back(G4->Momentum().Px());
712  fStubTruePy.push_back(G4->Momentum().Py());
713  fStubTruePz.push_back(G4->Momentum().Pz());
714  }
715  else {
716  fStubTruePdg.push_back(-1);
717  fStubTrueID.push_back(-1);
718  fStubTrueKE.push_back(-1);
719  fStubTrueLength.push_back(-1);
720 
721  fStubTruePx.push_back(-1);
722  fStubTruePy.push_back(-1);
723  fStubTruePz.push_back(-1);
724  }
725 
726  // intra plane matching
727  {
728  unsigned start_size = fStubMatch.size();
729  for (unsigned j_stub = 0; j_stub < stubs.size(); j_stub++) {
730  if (i_stub == j_stub) continue;
731  if (stubs[i_stub].stub.plane.size() != 1 || stubs[j_stub].stub.plane.size() != 1) continue; // Ignore multi-plane stubs
732  if (stubs[i_stub].stub.plane.front() == stubs[j_stub].stub.plane.front()) {
733  fStubMatch.push_back(j_stub);
734  fStubMatchOverlaps.push_back(sbn::StubContains(stubs[i_stub], stubs[j_stub]));
735  fStubMatchDot.push_back(sbn::StubDirectionDot(stubs[i_stub], stubs[j_stub], geo, dprop));
736  }
737  }
738  fStubMatchLength.push_back(fStubMatch.size() - start_size);
739  }
740 
741  // inter plane matching
742  {
743  unsigned start_size = fStubXPlaneMatch.size();
744  for (unsigned j_stub = 0; j_stub < stubs.size(); j_stub++) {
745  if (i_stub == j_stub) continue;
746  if (stubs[i_stub].stub.plane.size() != 1 || stubs[j_stub].stub.plane.size() != 1) continue; // Ignore multi-plane stubs
747  if (stubs[i_stub].stub.plane.front().Plane != stubs[j_stub].stub.plane.front().Plane) {
748  fStubXPlaneMatch.push_back(j_stub);
749  fStubXPlaneMatchTOff.push_back(sbn::StubTimeOffset(stubs[i_stub], stubs[j_stub], clock_data, dprop));
750  fStubXPlaneMatchQOff.push_back(sbn::StubChargeOffset(stubs[i_stub], stubs[j_stub]));
751  fStubXPlaneMatchPeakQOff.push_back(sbn::StubPeakChargeOffset(stubs[i_stub], stubs[j_stub]));
752  fStubXPlaneMatchdQdxOff.push_back((stubs[i_stub].stub.plane.front().TPC == stubs[j_stub].stub.plane.front().TPC) ?
753  sbn::StubPeakdQdxOffset(stubs[i_stub], stubs[j_stub], geo, sce, dprop) : std::numeric_limits<float>::signaling_NaN());
754  }
755  }
756  fStubXPlaneMatchLength.push_back(fStubXPlaneMatch.size() - start_size);
757  }
758 
759  } // end iterate over vertex-stubs
760 }
762  const std::vector<art::Ptr<sbn::VertexHit>> &hits,
763  const std::vector<art::Ptr<recob::Hit>> &hit_hits,
764  const detinfo::DetectorPropertiesData &dprop,
765  const detinfo::DetectorClocksData &clock_data,
766  const std::vector<art::Ptr<simb::MCParticle>> &trueParticles) {
767 
768  for (unsigned i_hit = 0; i_hit < hits.size(); i_hit++) {
769  const sbn::VertexHit &hit = *hits[i_hit];
770  unsigned plane = hit.wire.Plane;
771  fVertexHitPlane.push_back(plane);
772  fVertexHitWire.push_back(hit.wire.Wire);
773  fVertexHitPeakX.push_back(dprop.ConvertTicksToX(hit_hits[i_hit]->PeakTime(), hit_hits[i_hit]->WireID()));
774  fVertexHitCharge.push_back(hit.charge);
775  fVertexHitDist.push_back(hit.proj_dist_to_vertex);
776  fVertexHitVtxW.push_back(hit.vtxw);
777  fVertexHitdQdx.push_back(hit.dqdx);
778  fVertexHitSPID.push_back(hit.spID);
779  fVertexHitPitch.push_back(hit.pitch);
780  fVertexHitdEdx.push_back(hit.dedx);
781 
782  fVertexHitTrueEnergy.push_back(0.);
783  fVertexHitTrueProtonEnergy.push_back(0.);
784  fVertexHitTrueBraggProtonEnergy.push_back(0.);
785 
786  fVertexHitTrueX.push_back(0.);
787  fVertexHitTrueY.push_back(0.);
788  fVertexHitTrueZ.push_back(0.);
789 
790  // Get the matching energy of the hit
791  art::ServiceHandle<cheat::BackTrackerService> bt;
792  std::vector<sim::IDE> hit_ides;
793  try {
794  std::vector<sim::IDE> try_get_hit_ides = bt->HitToAvgSimIDEs(clock_data, *hit_hits[i_hit]);
795  hit_ides = try_get_hit_ides;
796  }
797  catch(...) {}
798 
799  for (unsigned i_ide = 0; i_ide < hit_ides.size(); i_ide++) {
800  fVertexHitTrueEnergy.back() += hit_ides[i_ide].energy;
801  fVertexHitTrueX.back() += hit_ides[i_ide].energy * hit_ides[i_ide].x;
802  fVertexHitTrueY.back() += hit_ides[i_ide].energy * hit_ides[i_ide].y;
803  fVertexHitTrueZ.back() += hit_ides[i_ide].energy * hit_ides[i_ide].z;
804 
805  for (unsigned i_g4 = 0; i_g4 < trueParticles.size(); i_g4++) {
806  if (abs(hit_ides[i_ide].trackID) == trueParticles[i_g4]->TrackId()) {
807  if (abs(trueParticles[i_g4]->PdgCode()) == 2212) {
808  fVertexHitTrueProtonEnergy.back() += hit_ides[i_ide].energy;
809  TVector3 ide_pos(hit_ides[i_ide].x, hit_ides[i_ide].y, hit_ides[i_ide].z);
810  if ((trueParticles[i_g4]->EndPosition().Vect() - ide_pos).Mag() < 0.5) {
811  fVertexHitTrueBraggProtonEnergy.back() += hit_ides[i_ide].energy;
812  }
813  }
814  break;
815  }
816  }
817  }
818 
819  if (hit_ides.size()) {
820  fVertexHitTrueX.back() /= fVertexHitTrueEnergy.back();
821  fVertexHitTrueY.back() /= fVertexHitTrueEnergy.back();
822  fVertexHitTrueZ.back() /= fVertexHitTrueEnergy.back();
823  }
824 
825  } // end iterate over hits
826 }
827 
828 void sbn::NuVertexChargeTree::FillNeutrino(const simb::MCTruth &nu,
829  const recob::Vertex &vert,
830  const std::vector<art::Ptr<recob::PFParticle>> &slice_pfps,
831  const std::vector<std::vector<std::pair<int, float>>> &slice_pfp_matches,
832  const std::vector<art::Ptr<simb::MCParticle>> &g4_mcparticles,
833  const std::vector<const sim::GeneratedParticleInfo *> &infos,
834  const geo::GeometryCore &geo,
835  const detinfo::DetectorPropertiesData &dprop) {
836 
837  art::ServiceHandle<cheat::BackTrackerService> backtracker;
838  // TODO: fix -- for now, use a null space-charge service
839  const spacecharge::SpaceCharge *sce = lar::providerFrom<spacecharge::SpaceChargeService>();
840  // If we are not correcting for SCE, then blank out the service
841  if (!fCorrectSCE) sce = nullptr;
842 
843  TVector3 vpos(vert.position().X(), vert.position().Y(), vert.position().Z());
844 
845  if (nu.NeutrinoSet()) {
846  fRecoVertDist = (nu.GetNeutrino().Nu().Position().Vect() - vpos).Mag();
847 
848  fNuE = nu.GetNeutrino().Nu().E();
849  fNuMode = nu.GetNeutrino().Mode();
850  fNuIntType = nu.GetNeutrino().InteractionType();
851  }
852  else {
853  fRecoVertDist = (nu.GetParticle(0).Position().Vect() - vpos).Mag();
854 
855  fNuE = -1;
856  fNuMode = -1;
857  fNuIntType = -1;
858  }
859 
860  // save each stable final-state particle
861  for (int i_part = 0; i_part < nu.NParticles(); i_part++) {
862  const simb::MCParticle &particle = nu.GetParticle(i_part);
863  // is stable?
864  if (particle.StatusCode() != 1) continue;
865 
866  // std::cout << "Stable FSP -- PdgID: " << particle.PdgCode() << " E: " << (particle.Momentum().E() - particle.Momentum().M()) << std::endl;
867 
868  // Find the corresponding G4 particle
869  const simb::MCParticle *G4 = Genie2G4MCParticle(particle, nu, g4_mcparticles, infos);
870 
871  if (!G4) continue;
872  // std::cout << "Tracked by G4!\n";
873 
874  // lookup its hits
875 
876  // save some crap
877  fFSPPx.push_back(particle.Momentum().Px());
878  fFSPPy.push_back(particle.Momentum().Py());
879  fFSPPz.push_back(particle.Momentum().Pz());
880 
881  fFSPStartX.push_back(G4->Position().X());
882  fFSPStartY.push_back(G4->Position().Y());
883  fFSPStartZ.push_back(G4->Position().Z());
884  fFSPEndX.push_back(G4->EndPosition().X());
885  fFSPEndY.push_back(G4->EndPosition().Y());
886  fFSPEndZ.push_back(G4->EndPosition().Z());
887 
888  fFSPE.push_back(particle.Momentum().E());
889  fFSPKE.push_back(particle.Momentum().E() - particle.Momentum().M());
890  fFSPPID.push_back(particle.PdgCode());
891 
892  fFSPLen.push_back((G4->Position().Vect() - G4->EndPosition().Vect()).Mag());
893 
894  bool is_stopping = (G4->EndProcess() == "Decay" ||
895  G4->EndProcess() == "CoupledTransportation" ||
896  G4->EndProcess() == "FastScintillation" ||
897  G4->EndProcess() == "muMinusCaptureAtRest" ||
898  G4->EndProcess() == "LArVoxelReadoutScoringProcess");
899  fFSPIsStopping.push_back(is_stopping);
900 
901  // see if there is a match
902  //
903  // Total up the energy fromthis particle
904  float thisVisE = 0.;
905  float thisQ = 0.;
906 
907  std::map<geo::WireID, float> chargemap;
908  for (geo::View_t view: geo.Views()) {
909  std::vector<const sim::IDE*> particle_ides(backtracker->TrackIdToSimIDEs_Ps(G4->TrackId(), view));
910  for (const sim::IDE *ide: particle_ides) {
911  thisVisE += ide->energy;
912 
913  // Correct for electron lifetime
914  geo::Point_t p {ide->x, ide->y, ide->z};
915  geo::TPCGeo const* tpc = geo.PositionToTPCptr(p);
916  if (tpc) {
917  float driftT = tpc->FirstPlane().DistanceFromPlane(p) / dprop.DriftVelocity();
918  thisQ += ide->numElectrons * exp(driftT / dprop.ElectronLifetime());
919 
920  geo::PlaneGeo const& plane = tpc->Plane(view);
921  try {
922  geo::WireID w = plane.NearestWireID(p);
923  chargemap[w] += ide->numElectrons * exp(driftT / dprop.ElectronLifetime());
924  }
925  catch(geo::InvalidWireError const&) {}
926  }
927  }
928  }
929 
930  fFSPVisE.push_back(thisVisE / 3. /* average over each plane */);
931  fFSPQ.push_back(thisQ / 3.);
932 
933  for (unsigned p = 0; p < 3; p++) {
934  float maxQ = -1;
935  for (auto const &pair: chargemap) {
936  if (pair.first.Plane == p) {
937  if (pair.second > maxQ) maxQ = pair.second;
938  }
939  }
940 
941  if (p == 0) fFSPMaxQ0.push_back(maxQ);
942  if (p == 1) fFSPMaxQ1.push_back(maxQ);
943  if (p == 2) fFSPMaxQ2.push_back(maxQ);
944  }
945 
946  geo::Point_t start_loc(particle.Position().Vect());
947  geo::Vector_t start_dir(particle.Momentum().Vect().Unit());
948  geo::TPCID firstTPC = geo.FindTPCAtPosition(start_loc);
949  if (firstTPC) {
950  fFSPPitch0.push_back(sbn::GetPitch(&geo, sce, start_loc, start_dir, geo.View(geo::PlaneID(firstTPC, 0)), firstTPC, true, true));
951  fFSPPitch1.push_back(sbn::GetPitch(&geo, sce, start_loc, start_dir, geo.View(geo::PlaneID(firstTPC, 1)), firstTPC, true, true));
952  fFSPPitch2.push_back(sbn::GetPitch(&geo, sce, start_loc, start_dir, geo.View(geo::PlaneID(firstTPC, 2)), firstTPC, true, true));
953  }
954  else {
955  fFSPPitch0.push_back(-1);
956  fFSPPitch1.push_back(-1);
957  fFSPPitch2.push_back(-1);
958  }
959 
960  bool found_match = false;
961  bool primary_match = false;
962  int pfp_pdgid = -1;
963  bool is_primary = false;
964  for (unsigned i_pfp = 0; i_pfp < slice_pfp_matches.size(); i_pfp++) {
965  for (unsigned i_match = 0; i_match < slice_pfp_matches[i_pfp].size(); i_match++) {
966 
967  if (slice_pfp_matches[i_pfp][i_match].first == G4->TrackId() &&
968  (slice_pfp_matches[i_pfp][i_match].second / thisVisE > 0.5)) {
969  found_match = true;
970  primary_match = i_match == 0;
971  pfp_pdgid = slice_pfps[i_pfp]->PdgCode();
972 
973  is_primary = slice_pfps[i_pfp]->IsPrimary();
974  if (!is_primary) {
975  int parent = slice_pfps[i_pfp]->Parent();
976  for (unsigned j_pfp = 0; j_pfp < slice_pfps.size(); j_pfp++) {
977  if ((int)slice_pfps[j_pfp]->Self() == parent) {
978  is_primary = slice_pfps[j_pfp]->IsPrimary() && lar_pandora::LArPandoraHelper::IsNeutrino(slice_pfps[j_pfp]);
979  break;
980  }
981  }
982  }
983 
984  // std::cout << "Found match! For particle ID: " << particle.PdgCode() << " gen ID: " << particle.TrackId() << std::endl;
985  // std::cout << "G4 particleID: " << G4->PdgCode() << " track ID: " << G4->TrackId() << " vis E: " << thisVisE << std::endl;
986  // std::cout << "Match info\n";
987  // for (unsigned i_match = 0; i_match < slice_pfp_matches[i_pfp].size(); i_match++) {
988  // std::cout << "Match ID: " << slice_pfp_matches[i_pfp][i_match].first << " E: " << slice_pfp_matches[i_pfp][i_match].second << std::endl;
989  // }
990 
991  break;
992  }
993  }
994  if (found_match) break;
995  }
996 
997  fFSPMatched.push_back(found_match);
998  fFSPMatchedPFPPrimary.push_back(is_primary);
999  fFSPMatchedPID.push_back(pfp_pdgid);
1000  fFSPMtachedPrimary.push_back(primary_match);
1001 
1002  }
1003 }
1004 
1005 void sbn::NuVertexChargeTree::analyze(art::Event const& evt) {
1006  // services
1007  art::ServiceHandle<cheat::BackTrackerService> backtracker;
1008  art::ServiceHandle<cheat::ParticleInventoryService> inventory_service;
1009  auto const clock_data = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
1010  auto const dprop =
1011  art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt, clock_data);
1012  const geo::GeometryCore *geo = lar::providerFrom<geo::Geometry>();
1013 
1014  // input data
1015  std::vector<std::vector<art::Ptr<recob::Slice>>> sliceList;
1016  std::vector<art::FindManyP<recob::Hit>> sliceHitList;
1017  std::vector<art::FindManyP<recob::PFParticle>> slicePFParticleList;
1018  std::vector<art::FindManyP<sbn::VertexHit>> sliceVertexHitList;
1019 
1020  for (unsigned i = 0; i < fPFParticleTags.size(); i++) {
1021  art::Handle<std::vector<recob::Slice>> slice_handle;
1022  evt.getByLabel(fPFParticleTags.at(i), slice_handle);
1023  sliceList.emplace_back();
1024  art::fill_ptr_vector(sliceList.back(), slice_handle);
1025  sliceHitList.emplace_back(sliceList.back(), evt, fPFParticleTags.at(i));
1026  slicePFParticleList.emplace_back(sliceList.back(), evt, fPFParticleTags.at(i));
1027  sliceVertexHitList.emplace_back(sliceList.back(), evt, fVertexHitTags.at(i));
1028  }
1029 
1030  // flatten
1031  std::vector<art::Ptr<recob::Slice>> slices;
1032  std::vector<std::vector<art::Ptr<recob::Hit>>> sliceHits;
1033 
1034  std::vector<std::vector<art::Ptr<recob::PFParticle>>> sliceParticles;
1035  std::vector<std::vector<std::vector<art::Ptr<recob::Hit>>>> sliceParticleHits;
1036  std::vector<std::vector<std::vector<art::Ptr<recob::Vertex>>>> sliceParticleVertexs;
1037 
1038  std::vector<std::vector<art::Ptr<sbn::VertexHit>>> sliceVertexHits;
1039  std::vector<std::vector<art::Ptr<recob::Vertex>>> sliceVertexHitVtxs;
1040  std::vector<std::vector<art::Ptr<recob::Hit>>> sliceVertexHitHits;
1041  std::vector<std::vector<art::Ptr<recob::SpacePoint>>> sliceVertexHitSPs;
1042  std::vector<std::vector<art::Ptr<sbn::Stub>>> sliceStubs;
1043  std::vector<std::vector<unsigned>> sliceStubHitInds;
1044  std::vector<std::vector<std::vector<art::Ptr<recob::Hit>>>> sliceStubHits;
1045  std::vector<std::vector<art::Ptr<recob::PFParticle>>> sliceStubPFPs;
1046  std::vector<std::vector<std::vector<art::Ptr<recob::Hit>>>> sliceStubPFPHits;
1047 
1048  for (unsigned i = 0; i < sliceList.size(); i++) {
1049  slices.insert(slices.end(), sliceList[i].begin(), sliceList[i].end());
1050  for (unsigned j = 0; j < sliceList[i].size(); j++) {
1051  sliceHits.push_back(sliceHitList[i].at(j));
1052  sliceParticles.push_back(slicePFParticleList[i].at(j));
1053 
1054  sliceParticleHits.emplace_back();
1055  art::FindManyP<recob::Cluster> sliceParticleClusters(sliceParticles.back(), evt, fPFParticleTags.at(i));
1056  for (unsigned i_pfp = 0; i_pfp < sliceParticles.back().size(); i_pfp++) {
1057  sliceParticleHits.back().emplace_back();
1058  const std::vector<art::Ptr<recob::Cluster>> &thisParticleClusters = sliceParticleClusters.at(i_pfp);
1059  art::FindManyP<recob::Hit> clusterHits(thisParticleClusters, evt, fPFParticleTags.at(i));
1060  for (unsigned i_clus = 0; i_clus < thisParticleClusters.size(); i_clus++) {
1061  sliceParticleHits.back().back().insert(sliceParticleHits.back().back().end(), clusterHits.at(i_clus).begin(), clusterHits.at(i_clus).end());
1062  }
1063  }
1064 
1065  sliceParticleVertexs.emplace_back();
1066  art::FindManyP<recob::Vertex> findSliceParticleVertexs(sliceParticles.back(), evt, fPFParticleTags.at(i));
1067  for (unsigned i_pfp = 0; i_pfp < sliceParticles.back().size(); i_pfp++) {
1068  sliceParticleVertexs.back().push_back(findSliceParticleVertexs.at(i_pfp));
1069  }
1070 
1071  sliceVertexHits.push_back(sliceVertexHitList[i].at(j));
1072 
1073  art::FindManyP<recob::Vertex> vertexHitVtxs(sliceVertexHits.back(), evt, fVertexHitTags.at(i));
1074  sliceVertexHitVtxs.emplace_back();
1075  for (unsigned i_vhit = 0; i_vhit < sliceVertexHits.back().size(); i_vhit++) {
1076  sliceVertexHitVtxs.back().push_back(vertexHitVtxs.at(i_vhit).at(0));
1077  }
1078 
1079  art::FindManyP<recob::Hit> vertexHitHits(sliceVertexHits.back(), evt, fVertexHitTags.at(i));
1080  sliceVertexHitHits.emplace_back();
1081  for (unsigned i_vhit = 0; i_vhit < sliceVertexHits.back().size(); i_vhit++) {
1082  sliceVertexHitHits.back().push_back(vertexHitHits.at(i_vhit).at(0));
1083  }
1084 
1085  art::Ptr<recob::SpacePoint> nullSP;
1086  art::FindManyP<recob::SpacePoint> vertexHitSPs(sliceVertexHitHits.back(), evt, fPFParticleTags.at(i));
1087  sliceVertexHitSPs.emplace_back();
1088  for (unsigned i_sp = 0; i_sp < sliceVertexHitHits.back().size(); i_sp++) {
1089  const std::vector<art::Ptr<recob::SpacePoint>> &this_sp = vertexHitSPs.at(i_sp);
1090  if (this_sp.size()) sliceVertexHitSPs.back().push_back(this_sp.at(0));
1091  else sliceVertexHitSPs.back().push_back(nullSP);
1092  }
1093 
1094  // art::Ptr<sbn::Stub> nullVH;
1095  art::FindManyP<sbn::Stub> vertexStubs(sliceVertexHits.back(), evt, fStubTags.at(i));
1096  sliceStubs.emplace_back();
1097  sliceStubHitInds.emplace_back();
1098  for (unsigned i_stub = 0; i_stub < sliceVertexHits.back().size(); i_stub++) {
1099  const std::vector<art::Ptr<sbn::Stub>> &this_vh = vertexStubs.at(i_stub);
1100  for (unsigned i_vh_stub = 0; i_vh_stub < this_vh.size(); i_vh_stub++) {
1101  sliceStubs.back().push_back(this_vh.at(i_vh_stub));
1102  sliceStubHitInds.back().push_back(i_stub);
1103  }
1104  }
1105 
1106  art::FindManyP<recob::Hit> vertexStubHits(sliceStubs.back(), evt, fStubTags.at(i));
1107  sliceStubHits.emplace_back();
1108  for (unsigned i_stub = 0; i_stub < sliceStubs.back().size(); i_stub++) {
1109  sliceStubHits.back().push_back(vertexStubHits.at(i_stub));
1110  }
1111 
1112  art::FindManyP<recob::PFParticle> vertexStubPFPs(sliceStubs.back(), evt, fStubTags.at(i));
1113  art::Ptr<recob::PFParticle> nullPFP;
1114  sliceStubPFPs.emplace_back();
1115  for (unsigned i_stub = 0; i_stub < sliceStubs.back().size(); i_stub++) {
1116  const std::vector<art::Ptr<recob::PFParticle>> &thisStubPFP = vertexStubPFPs.at(i_stub);
1117  if (thisStubPFP.size()) sliceStubPFPs.back().push_back(thisStubPFP.at(0));
1118  else sliceStubPFPs.back().push_back(nullPFP);
1119  }
1120 
1121  sliceStubPFPHits.emplace_back();
1122  for (unsigned i_stub = 0; i_stub < sliceStubPFPs.back().size(); i_stub++) {
1123  bool found = false;
1124  for (unsigned i_pfp = 0; i_pfp < sliceParticles.back().size(); i_pfp++) {
1125  if (sliceStubPFPs.back()[i_stub] == sliceParticles.back()[i_pfp]) {
1126  sliceStubPFPHits.back().push_back(sliceParticleHits.back()[i_pfp]);
1127  found = true;
1128  break;
1129  }
1130  }
1131  if (!found) {
1132  sliceStubPFPHits.back().emplace_back();
1133  }
1134  }
1135 
1136  } // end iterate over slices
1137  } // end iterate over pfp-tags
1138 
1139  // also get truth stuff
1140  art::Handle<std::vector<simb::MCTruth>> trueNuHandle;
1141  evt.getByLabel("generator", trueNuHandle);
1142  std::vector<art::Ptr<simb::MCTruth>> trueNus;
1143  art::fill_ptr_vector(trueNus, trueNuHandle);
1144 
1145  art::Handle<std::vector<simb::MCParticle>> trueParticleHandle;
1146  evt.getByLabel("largeant", trueParticleHandle);
1147  std::vector<art::Ptr<simb::MCParticle>> trueParticles;
1148  art::fill_ptr_vector(trueParticles, trueParticleHandle);
1149 
1150  // get associations from MCTruth information to truth
1151  art::FindManyP<simb::MCParticle, sim::GeneratedParticleInfo> truth_to_particles(trueNus, evt, "largeant");
1152 
1153  // for (unsigned i_g4 = 0; i_g4 < trueParticles.size(); i_g4++) {
1154  // const simb::MCParticle &particle = *trueParticles[i_g4];
1155  // std::cout << "particle ID: " << particle.TrackId() << " pdg: " << particle.PdgCode() << " start E: " << (particle.E() - particle.Momentum().M()) << " start X: " << particle.Vx() << std::endl;
1156  // }
1157 
1158  // iterate over each neutrino
1159  for (unsigned i_nu = 0; i_nu < trueNus.size(); i_nu++) {
1160  const simb::MCTruth &nu = *trueNus[i_nu];
1161  // require inside fiducial volume
1162  TVector3 true_vertex = nu.NeutrinoSet() ? nu.GetNeutrino().Nu().Position().Vect() : nu.GetParticle(0).Position().Vect();
1163  if (!InFV(true_vertex)) continue;
1164 
1165  // try to do reco-matching
1166  //
1167  // Total up the visible energy of this neutrino
1168  float visE = 0.;
1169  for (unsigned i_g4 = 0; i_g4 < trueParticles.size(); i_g4++) {
1170  const simb::MCParticle &particle = *trueParticles[i_g4];
1171  art::Ptr<simb::MCTruth> truth = inventory_service->TrackIdToMCTruth_P(particle.TrackId());
1172  if (truth == trueNus[i_nu]) {
1173  std::vector<const sim::IDE*> particle_ides(backtracker->TrackIdToSimIDEs_Ps(particle.TrackId()));
1174  for (const sim::IDE *ide: particle_ides) visE += ide->energy;
1175  }
1176  }
1177 
1178  int slice_match = -1;
1179  // see if the visible energy from any slice matches
1180  for (unsigned i_slice = 0; i_slice < slices.size(); i_slice++) {
1181  const recob::Slice &slice = *slices[i_slice];
1182  (void) slice;
1183  float matchingE = 0.;
1184  float totalE = 0.;
1185  std::vector<std::pair<int, float>> matches = CAFRecoUtils::AllTrueParticleIDEnergyMatches(clock_data, sliceHits.at(i_slice));
1186  for (unsigned i_match = 0; i_match < matches.size(); i_match++) {
1187  totalE += matches[i_match].second;
1188  }
1189 
1190  for (unsigned i_g4 = 0; i_g4 < trueParticles.size(); i_g4++) {
1191  for (unsigned i_match = 0; i_match < matches.size(); i_match++) {
1192  if (matches[i_match].first == trueParticles[i_g4]->TrackId()) {
1193  art::Ptr<simb::MCTruth> truth = inventory_service->TrackIdToMCTruth_P(trueParticles[i_g4]->TrackId());
1194  if (truth == trueNus[i_nu]) {
1195  matchingE += matches[i_match].second;
1196  }
1197  break;
1198  }
1199  }
1200  }
1201 
1202  // std::cout << "Slice: " << i_slice << " match E: " << matchingE << " vis E: " << visE << " total E: " << totalE << std::endl;
1203 
1204  if (matchingE / visE > 0.5) {
1205  if (matchingE / totalE > 0.5) slice_match = i_slice;
1206  break;
1207  }
1208  }
1209 
1210  if (slice_match < 0) continue;
1211  // We found a matching slice!
1212 
1213  // Do reco stuff
1214  // Collect reco stuff
1215  const std::vector<art::Ptr<recob::PFParticle>> thisSliceParticles = sliceParticles.at(slice_match);
1216  const std::vector<std::vector<art::Ptr<recob::Hit>>> thisSliceParticleHits = sliceParticleHits.at(slice_match);
1217  const std::vector<std::vector<art::Ptr<recob::Vertex>>> thisSliceParticleVertexs = sliceParticleVertexs.at(slice_match);
1218 
1219  const std::vector<art::Ptr<sbn::VertexHit>> &thisVertexHits = sliceVertexHits.at(slice_match);
1220  const std::vector<art::Ptr<recob::Hit>> &thisVertexHitHits = sliceVertexHitHits.at(slice_match);
1221  const std::vector<art::Ptr<recob::SpacePoint>> &thisVertexHitSPs = sliceVertexHitSPs.at(slice_match);
1222  const std::vector<art::Ptr<recob::Vertex>> &thisVertexHitVtxs = sliceVertexHitVtxs.at(slice_match);
1223 
1224  const std::vector<art::Ptr<sbn::Stub>> &thisStubs = sliceStubs.at(slice_match);
1225  const std::vector<std::vector<art::Ptr<recob::Hit>>> &thisStubHits = sliceStubHits.at(slice_match);
1226  const std::vector<unsigned> &thisStubHitInds = sliceStubHitInds.at(slice_match);
1227  const std::vector<art::Ptr<recob::PFParticle>> &thisStubPFPs = sliceStubPFPs.at(slice_match);
1228  const std::vector<std::vector<art::Ptr<recob::Hit>>> &thisStubPFPHits = sliceStubPFPHits.at(slice_match);
1229 
1230  // Build the stub infos
1231  std::vector<sbn::StubInfo> thisStubInfos;
1232  for (unsigned i = 0; i < thisStubs.size(); i++) {
1233  thisStubInfos.emplace_back();
1234 
1235  sbn::StubInfo& newStub = thisStubInfos.back();
1236 
1237  newStub.stub = *thisStubs[i];
1238  newStub.pfp = thisStubPFPs.at(i);
1239  newStub.hits = thisStubHits.at(i);
1240  newStub.vhit = thisVertexHits.at(thisStubHitInds[i]);
1241  newStub.vhit_hit = thisVertexHitHits.at(thisStubHitInds[i]);
1242  }
1243 
1244  (void) thisVertexHitSPs;
1245  (void) thisVertexHitVtxs;
1246  //for (unsigned i_hit = 0; i_hit < thisVertexHitHits.size(); i_hit++) {
1247  // std::cout << "Hit: " << i_hit << std::endl;
1248  // art::Ptr<recob::SpacePoint> sp = thisVertexHitSPs.at(i_hit);
1249  // if (sp) {
1250  // std::cout << "SP! " << sp->ID() << " X: " << sp->XYZ()[0] << " Y: " << sp->XYZ()[1] << " Z: " << sp->XYZ()[2] << std::endl;
1251  // }
1252  //}
1253 
1254  // Get the primary vertex
1255  art::Ptr<recob::Vertex> vert;
1256  for (unsigned i_pfp = 0; i_pfp < thisSliceParticles.size(); i_pfp++) {
1257  if (thisSliceParticles[i_pfp]->IsPrimary() &&
1258  /* TODO: remove. Needed because of issue in SCE correction module */ thisSliceParticleVertexs.at(i_pfp).size()) {
1259  vert = thisSliceParticleVertexs.at(i_pfp).at(0);
1260  break;
1261  }
1262  }
1263 
1264  double badpos[3] {-999., -999., -999.};
1265  recob::Vertex badvert(badpos);
1266  const recob::Vertex &nu_vert = (vert) ? *vert : badvert;
1267 
1268  // Lookup truth-matching
1269  std::vector<std::vector<std::pair<int, float>>> thisSlicePFPMatches;
1270  for (unsigned i_pfp = 0; i_pfp < thisSliceParticles.size(); i_pfp++) {
1271  std::vector<std::pair<int, float>> matches = CAFRecoUtils::AllTrueParticleIDEnergyMatches(clock_data, thisSliceParticleHits.at(i_pfp));
1272  // sort
1273  std::sort(matches.begin(), matches.end(),
1274  [](auto const &lhs, auto const &rhs) {
1275  return lhs.second > rhs.second;
1276  });
1277  thisSlicePFPMatches.push_back(matches);
1278  }
1279 
1280  Clear();
1281  FillMeta(evt);
1282 
1283  // save the true-neutrino info
1284  FillNeutrino(nu, nu_vert, thisSliceParticles, thisSlicePFPMatches, truth_to_particles.at(i_nu), truth_to_particles.data(i_nu), *geo, dprop);
1285 
1286  // The vertex hits!
1287  FillVertexHits(thisVertexHits, thisVertexHitHits, dprop, clock_data, trueParticles);
1288 
1289  FillStubs(thisStubInfos, thisStubHitInds, geo, dprop, clock_data, trueParticles);
1290 
1291  FillStubPFPs(thisStubPFPs, thisStubPFPHits, clock_data, trueParticles);
1292 
1293  FillSlice(thisSliceParticles);
1294 
1295  _tree->Fill();
1296  }
1297 }
1298 
1299 DEFINE_ART_MODULE(sbn::NuVertexChargeTree)
float StubChargeOffset(const sbn::StubInfo &A, const sbn::StubInfo &B)
Difference of the total charge between two stubs.
float StubTimeOffset(const sbn::StubInfo &A, const sbn::StubInfo &B, const detinfo::DetectorClocksData &dclock, const detinfo::DetectorPropertiesData &dprop)
process_name opflash particleana ie ie ie z
std::vector< float > fVertexHitTrueZ
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
Definition: geo_vectors.h:164
std::vector< float > fStubXPlaneMatchdQdxOff
float dqdx
charge/pitch [#elec/cm]
Definition: VertexHit.h:20
Utilities related to art service access.
std::vector< float > fStubXPlaneMatchPeakQOff
float StubPeakdQdxOffset(const sbn::StubInfo &A, const sbn::StubInfo &B, const geo::GeometryCore *geo, const spacecharge::SpaceCharge *sce, const detinfo::DetectorPropertiesData &dprop)
Difference of the endpoint dQ/dx between two stubs.
std::vector< float > fVertexHitTrueY
const geo::GeometryCore * geometry
process_name opflash particleana ie x
std::vector< geo::PlaneID > plane
The plane ID.
Definition: Stub.h:25
std::vector< std::string > fStubTags
Analyzer module for use with sbn::Stub and sbn::VertexHit objects.
float dedx
Recombination corrected dQ/dx [MeV/cm].
Definition: VertexHit.h:21
static bool IsNeutrino(const art::Ptr< recob::PFParticle > particle)
Determine whether a particle has been reconstructed as a neutrino.
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
std::vector< geo::BoxBoundedGeo > fFiducialVolumes
std::vector< float > fVertexHitTrueEnergy
geo::WireID wire
Wire that the hit is on.
Definition: VertexHit.h:11
Declaration of signal hit object.
float StubDirectionDot(const sbn::StubInfo &A, const sbn::StubInfo &B, const geo::GeometryCore *geo, const detinfo::DetectorPropertiesData &dprop)
Computes the dot product of two stubs.
std::set< geo::View_t > const & Views() const
Returns a list of possible views in the detector.
std::vector< float > fVertexHitCharge
pdgs p
Definition: selectors.fcl:22
std::vector< std::vector< StubHit > > hits
Hits on each plane. Ordered vtx-&gt;end.
Definition: Stub.h:32
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
geo::Point_t end
End of Stub. Space charge corrected. [cm].
Definition: Stub.h:19
Geometry information for a single TPC.
Definition: TPCGeo.h:38
geo::PlaneGeo const & FirstPlane() const
Returns the first wire plane (the closest to TPC center).
Definition: TPCGeo.h:245
geo::BoxBoundedGeo const & ActiveBoundingBox() const
Returns the box of the active volume of this TPC.
Definition: TPCGeo.h:320
static bool IsShower(const art::Ptr< recob::PFParticle > particle)
Determine whether a particle has been reconstructed as shower-like.
geo::TPCGeo const * PositionToTPCptr(geo::Point_t const &point) const
Returns the TPC at specified location.
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:580
Internal struct: contains information on stub and other associated data products. ...
process_name hit
Definition: cheaterreco.fcl:51
bool IsPrimary(const caf::SRTrueParticleProxy &p)
Whether this is a primary particle or generated by a secondary interaction.
std::vector< float > fVertexHitTrueX
float CoreCharge(unsigned plane_index=0) const
Helper functions.
Definition: Stub.cxx:25
geo::Point_t vtx
Interaction Vertex / Start of Stub. Space charge corrected. [cm].
Definition: Stub.h:18
Definition of vertex object for LArSoft.
Definition: Vertex.h:35
float charge
Calibrated and lifetime-corrected charge on the hit [#elec].
Definition: VertexHit.h:12
BEGIN_PROLOG TPC
fRangeCalculator(p.get< float >("MinTrackLength", 0.1))
std::vector< std::string > fPFParticleTags
TPC_iterator begin_TPC() const
Returns an iterator pointing to the first TPC in the detector.
def InFV
Definition: selection.py:13
std::vector< float > vtx_w
Wire coordinate of the vertex on this plane.
Definition: Stub.h:29
std::vector< art::Ptr< recob::Hit > > hits
while getopts h
geo::TPCID FindTPCAtPosition(double const worldLoc[3]) const
Returns the ID of the TPC at specified location.
std::vector< std::pair< int, float > > AllTrueParticleIDEnergyMatches(const detinfo::DetectorClocksData &clockData, const std::vector< art::Ptr< recob::Hit > > &hits, bool rollup_unsaved_ids=1)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
void analyze(art::Event const &e) override
Access the description of detector geometry.
T abs(T value)
Collection of exceptions for Geometry system.
std::vector< std::string > fVertexHitTags
process_name opflash particleana ie ie y
Ionization at a point of the TPC sensitive volume.
Definition: SimChannel.h:86
NuVertexChargeTree & operator=(NuVertexChargeTree const &)=delete
NuVertexChargeTree(fhicl::ParameterSet const &p)
std::vector< short > hit_w
Wire of the end point hit on this plane.
Definition: Stub.h:30
Geometry information for a single wire plane.The plane is represented in the geometry by a solid whic...
Definition: PlaneGeo.h:82
void FillVertexHits(const std::vector< art::Ptr< sbn::VertexHit >> &hits, const std::vector< art::Ptr< recob::Hit >> &hit_hits, const detinfo::DetectorPropertiesData &dprop, const detinfo::DetectorClocksData &clock_data, const std::vector< art::Ptr< simb::MCParticle >> &trueParticles)
bool StubContains(const sbn::StubInfo &A, const sbn::StubInfo &B)
Returns whether stub A contains stub B.
float proj_dist_to_vertex
Distnace from the hit to the vertex on the wireplane.
Definition: VertexHit.h:13
art::Ptr< recob::Hit > vhit_hit
double GetPitch(const geo::GeometryCore *geo, const spacecharge::SpaceCharge *sce, geo::Point_t loc, geo::Vector_t dir, geo::View_t view, geo::TPCID tpc, bool correct_sce, bool track_is_sce_corrected, float xsign=1.)
Computes the track-pitch on a plane given an input direction and location.
std::vector< std::vector< geo::BoxBoundedGeo > > fTPCVolumes
double DriftVelocity(double efield=0., double temperature=0.) const
cm/us
std::vector< float > fStubTrueLength
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
j template void())
Definition: json.hpp:3108
Description of geometry of one entire detector.
Declaration of cluster object.
View_t View(geo::PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
void FillStubPFPs(const std::vector< art::Ptr< recob::PFParticle >> &stub_pfps, const std::vector< std::vector< art::Ptr< recob::Hit >>> &stub_pfp_hits, const detinfo::DetectorClocksData &clock_data, const std::vector< art::Ptr< simb::MCParticle >> &trueParticles)
void FillNeutrino(const simb::MCTruth &nu, const recob::Vertex &vert, const std::vector< art::Ptr< recob::PFParticle >> &slice_pfps, const std::vector< std::vector< std::pair< int, float >>> &slice_pfp_matches, const std::vector< art::Ptr< simb::MCParticle >> &g4_mcparticles, const std::vector< const sim::GeneratedParticleInfo * > &infos, const geo::GeometryCore &geo, const detinfo::DetectorPropertiesData &dprop)
trkf::TrackMomentumCalculator fRangeCalculator
float efield_end
The E-Field at the stub end point.
Definition: Stub.h:21
void respondToOpenInputFile(const art::FileBlock &fb) override
Provides recob::Track data product.
float efield_vtx
The E-Field at the reconstructed vertex.
Definition: Stub.h:22
Provides a base class aware of world box coordinates.
std::vector< TCSlice > slices
Definition: DataStructs.cxx:13
void FillMeta(const art::Event &evt)
std::array< float, 6 > fFiducialInset
double ConvertTicksToX(double ticks, int p, int t, int c) const
IteratorBox< cryostat_iterator,&GeometryCore::begin_cryostat,&GeometryCore::end_cryostat > IterateCryostats() const
Enables ranged-for loops on all cryostats of the detector.
art::Ptr< sbn::VertexHit > vhit
std::vector< float > fVertexHitTrueBraggProtonEnergy
std::vector< float > fVertexHitPeakX
const simb::MCParticle * Genie2G4MCParticle(const simb::MCParticle &genie_part, const simb::MCTruth &mctruth, const std::vector< art::Ptr< simb::MCParticle >> &g4_mcparticles, const std::vector< const sim::GeneratedParticleInfo * > infos)
float pitch
Computed pitch of a track traversing from the vertex to this hit. Space charge corrected. [cm].
Definition: VertexHit.h:19
std::vector< float > fStubXPlaneMatchTOff
std::vector< bool > fFSPMtachedPrimary
Contains all timing reference information for the detector.
double DistanceFromPlane(geo::Point_t const &point) const
Returns the distance of the specified point from the wire plane.
Definition: PlaneGeo.h:621
std::vector< float > fVertexHitPitch
std::vector< bool > fFSPMatchedPFPPrimary
static bool IsTrack(const art::Ptr< recob::PFParticle > particle)
Determine whether a particle has been reconstructed as track-like.
do i e
Exception thrown on invalid wire number.
Definition: Exceptions.h:42
std::vector< float > fVertexHitTrueProtonEnergy
int spID
ID of the SpacePoint associated with this hit.
Definition: VertexHit.h:16
std::vector< float > trkpitch
Pitch of the matched track on each wire [cm].
Definition: Stub.h:28
PlaneGeo const & Plane(geo::View_t view) const
Return the plane in the tpc with View_t view.
Definition: TPCGeo.cxx:263
art::ServiceHandle< art::TFileService > tfs
float StubPeakChargeOffset(const sbn::StubInfo &A, const sbn::StubInfo &B)
Difference of the endpoint charge between two stubs.
int CoreNHit(unsigned plane_index=0) const
Returns the number of hits along the core of the stub on the given plane index.
Definition: Stub.cxx:41
TCEvent evt
Definition: DataStructs.cxx:8
Definition: Stub.h:16
std::vector< int > fStubXPlaneMatchLength
Forward iterator browsing all geometry elements in the detector.
Definition: GeometryCore.h:727
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:184
std::vector< float > pitch
Pitch of stub on each wire [cm].
Definition: Stub.h:27
helper function for LArPandoraInterface producer module
BEGIN_PROLOG SN nu
const Point_t & position() const
Return vertex 3D position.
Definition: Vertex.h:60
art framework interface to geometry description
void FillStubs(const std::vector< sbn::StubInfo > &stubs, const std::vector< unsigned > &stub_hit_inds, const geo::GeometryCore *geo, const detinfo::DetectorPropertiesData &dprop, const detinfo::DetectorClocksData &clock_data, const std::vector< art::Ptr< simb::MCParticle >> &trueParticles)
void FillSlice(const std::vector< art::Ptr< recob::PFParticle >> &slice_particles)
std::vector< float > fStubXPlaneMatchQOff
TPC_iterator end_TPC() const
Returns an iterator pointing after the last TPC in the detector.
float vtxw
Wire of the vertex associated with this hit. Not space charge corrected. [cm].
Definition: VertexHit.h:14
art::Ptr< recob::PFParticle > pfp