All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CalorimetryAnalysis_module.cc
Go to the documentation of this file.
1 #ifndef SBN_ANALYSIS_CALORIMETRYANALYSIS_CXX
2 #define SBN_ANALYSIS_CALORIMETRYANALYSIS_CXX
3 
4 #include <iostream>
5 #include <map>
6 
7 #include "TDatabasePDG.h"
8 #include "TParticlePDG.h"
9 #include "art/Framework/Core/EDAnalyzer.h"
10 #include "canvas/Utilities/InputTag.h"
11 #include "fhiclcpp/ParameterSet.h"
12 #include "art/Framework/Core/FileBlock.h"
13 #include "art/Framework/Core/ModuleMacros.h"
14 #include "art/Framework/Principal/Event.h"
15 #include "art/Framework/Principal/Handle.h"
16 #include "art/Framework/Principal/SubRun.h"
17 #include "art/Framework/Services/Registry/ServiceHandle.h"
18 
19 #include "art_root_io/TFileService.h"
20 
21 #include "canvas/Persistency/Common/FindMany.h"
22 #include "canvas/Persistency/Common/FindManyP.h"
23 #include "canvas/Persistency/Common/FindOne.h"
24 #include "canvas/Persistency/Common/FindOneP.h"
25 #include "canvas/Persistency/Common/Ptr.h"
26 #include "canvas/Persistency/Common/PtrVector.h"
27 
28 
30 
32 
46 #include "nusimdata/SimulationBase/MCParticle.h"
47 #include "nusimdata/SimulationBase/MCTruth.h"
48 
51 
57 
58 // #include "larpandora/LArPandoraInterface/LArPandoraHelper.h"
59 
61 
62 
63 namespace analysis
64 {
65 ////////////////////////////////////////////////////////////////////////
66 //
67 // Class: CalorimetryAnalysis
68 // File: CalorimetryAnalysis.cc
69 //
70 // A basic analysis example
71 //
72 // Configuration parameters:
73 //
74 // TBD
75 //
76 // Created by Giuseppe Cerati (cerati@fnal.gov) on 03/15/2019
77 //
78 ////////////////////////////////////////////////////////////////////////
79 
80 // declare helper functions
81 void TrkDirectionAtXYZ(const recob::Track trk, const double x, const double y, const double z, float out[3]);
82 void True2RecoMappingXYZ(float t, float x, float y, float z, float out[3]);
83 float XYZtoPlanecoordinate(const float x, const float y, const float z, const int plane);
84 float distance3d(const float& x1, const float& y1, const float& z1,
85  const float& x2, const float& y2, const float& z2);
86 float ContainedLength(const TVector3 &v0, const TVector3 &v1,
87  const std::vector<geoalgo::AABox> &boxes);
88 void FillHits(const detinfo::DetectorClocksData &clockData,
89  const std::vector<art::Ptr<recob::Hit>> &hits,
90  std::vector<float> &charge_u,
91  std::vector<float> &charge_v,
92  std::vector<float> &charge_y,
93  std::vector<unsigned> &wire_u,
94  std::vector<unsigned> &wire_v,
95  std::vector<unsigned> &wire_y,
96  std::vector<unsigned> &channel_u,
97  std::vector<unsigned> &channel_v,
98  std::vector<unsigned> &channel_y,
99  std::vector<int> &multiplicity_u,
100  std::vector<int> &multiplicity_v,
101  std::vector<int> &multiplicity_y,
102  std::vector<float> &width_u,
103  std::vector<float> &width_v,
104  std::vector<float> &width_y,
105  std::vector<float> &time_u,
106  std::vector<float> &time_v,
107  std::vector<float> &time_y,
108  std::vector<unsigned> &nhit_u,
109  std::vector<unsigned> &nhit_v,
110  std::vector<unsigned> &nhit_y,
111  bool use_integral=true);
112 
113 class CalorimetryAnalysis : public art::EDAnalyzer
114 {
115 
116 public:
117  /**
118  * @brief Constructor
119  *
120  * @param pset
121  */
122  CalorimetryAnalysis(const fhicl::ParameterSet &pset);
123 
124  /**
125  * @brief Destructor
126  */
128 
129  /**
130  * @brief Analysis function
131  */
132  void analyze(art::Event const &e) override;
133 
134  /**
135  * @brief Fill Default info for event associated to neutrino
136  */
137  void fillDefault();
138 
139  /**
140  * @brief set branches for TTree
141  */
142  void setBranches(TTree *_tree);
143 
144  /**
145  * @brief reset ttree branches
146  */
147  void resetTTree(TTree *_tree);
148 
149  void respondToOpenInputFile(const art::FileBlock& fb) override {
150  (void) fb;
151  _fileno ++;
152  }
153 
154 private:
155 
156  // function that given a track and its calo info fills NTuple variables
157  void FillCalorimetry(art::Event const &e,
158  const std::vector<art::Ptr<recob::Wire>> &allWires,
159  const std::vector<art::Ptr<recob::Hit>> &allHits,
160  const art::Ptr<recob::PFParticle> &pfp,
161  const art::Ptr<recob::Track> &trk,
162  const std::vector<art::Ptr<recob::SpacePoint>> &spacepoints,
163  const std::vector<art::Ptr<anab::Calorimetry>> &calos,
164  const std::vector<art::Ptr<anab::ParticleID>> &pid,
165  const std::vector<art::Ptr<recob::Hit>> &areaHits,
166  const std::vector<art::Ptr<recob::Hit>> &trkHits,
167  const std::vector<art::Ptr<recob::Hit>> &caloHits,
168  const recob::MCSFitResult &muon_mcs,
169  const sbn::RangeP &muon_range,
170  const sbn::RangeP &proton_range,
171  const bool fData,
172  const std::vector<std::pair<int, float>> &particleMatches,
173  const art::Ptr<simb::MCParticle> &trueParticle,
174  const std::array<std::map<unsigned, std::vector<const sim::IDE*>>, 3> particle_ide_map,
175  const std::array<std::vector<const sim::IDE*>,3> &allIDEs,
176  const std::vector<geo::BoxBoundedGeo> &activeVolumes);
177 
178 
179  TParticlePDG *proton = TDatabasePDG::Instance()->GetParticle(2212);
180  TParticlePDG *muon = TDatabasePDG::Instance()->GetParticle(13);
181 
182  art::InputTag fPFPproducer;
183  art::InputTag fCALOproducer;
184  art::InputTag fPIDproducer;
185  art::InputTag fTRKproducer;
186  art::InputTag fT0producer;
187  art::InputTag fHitFilterproducer;
188  art::InputTag fAreaHitproducer;
189  std::vector<art::InputTag> fHitProducers;
190  art::InputTag fWireProducer;
191  std::string fMCSproducer;
192  std::string fRangeproducer;
194 
195  std::vector<std::vector<geo::BoxBoundedGeo>> fTPCVolumes;
196  std::vector<geo::BoxBoundedGeo> fActiveVolumes;
197 
198  TTree* _calo_tree;
199 
200  int _fileno;
201  int _run, _sub, _evt;
202  int _pfpno;
203  int _trkid;
204  // backtracking information
205  int _backtracked_pdg; // PDG code of backtracked particle
206  float _backtracked_e; // energy of backtracked particle
207  float _backtracked_deposited_e_u; // energy of backtracked particle
208  float _backtracked_deposited_e_v; // energy of backtracked particle
209  float _backtracked_deposited_e_y; // energy of backtracked particle
210  float _backtracked_purity; // purity of backtracking
211  float _backtracked_completeness; // completeness of backtracking
212  float _backtracked_overlay_purity; // purity of overlay
219 
220  std::vector<float> _backtracked_pc_q_u;
221  std::vector<float> _backtracked_pc_q_v;
222  std::vector<float> _backtracked_pc_q_y;
223 
224  std::vector<float> _backtracked_pc_e_u;
225  std::vector<float> _backtracked_pc_e_v;
226  std::vector<float> _backtracked_pc_e_y;
227 
228  std::vector<unsigned> _backtracked_c_u;
229  std::vector<unsigned> _backtracked_c_v;
230  std::vector<unsigned> _backtracked_c_y;
231 
232  std::vector<int> _backtracked_nloc_c_u;
233  std::vector<float> _backtracked_locx_c_u;
234  std::vector<float> _backtracked_locy_c_u;
235  std::vector<float> _backtracked_locz_c_u;
236  std::vector<float> _backtracked_dirx_c_u;
237  std::vector<float> _backtracked_diry_c_u;
238  std::vector<float> _backtracked_dirz_c_u;
239  std::vector<float> _backtracked_de_c_u;
240  std::vector<float> _backtracked_pitch_c_u;
241  std::vector<float> _backtracked_scepitch_c_u;
242 
243  std::vector<int> _backtracked_nloc_c_v;
244  std::vector<float> _backtracked_locx_c_v;
245  std::vector<float> _backtracked_locy_c_v;
246  std::vector<float> _backtracked_locz_c_v;
247  std::vector<float> _backtracked_dirx_c_v;
248  std::vector<float> _backtracked_diry_c_v;
249  std::vector<float> _backtracked_dirz_c_v;
250  std::vector<float> _backtracked_de_c_v;
251  std::vector<float> _backtracked_pitch_c_v;
252  std::vector<float> _backtracked_scepitch_c_v;
253 
254  std::vector<int> _backtracked_nloc_c_y;
255  std::vector<float> _backtracked_locx_c_y;
256  std::vector<float> _backtracked_locy_c_y;
257  std::vector<float> _backtracked_locz_c_y;
258  std::vector<float> _backtracked_dirx_c_y;
259  std::vector<float> _backtracked_diry_c_y;
260  std::vector<float> _backtracked_dirz_c_y;
261  std::vector<float> _backtracked_de_c_y;
262  std::vector<float> _backtracked_pitch_c_y;
263  std::vector<float> _backtracked_scepitch_c_y;
264 
265  std::vector<float> _backtracked_x;
266  std::vector<float> _backtracked_y;
267  std::vector<float> _backtracked_z;
268 
269  std::vector<float> _backtracked_dirx;
270  std::vector<float> _backtracked_diry;
271  std::vector<float> _backtracked_dirz;
272 
275 
279 
283 
297 
300 
303 
304  uint _generation; // generation, 1 is primary
305  uint _shr_daughters; // number of shower daughters
306  uint _trk_daughters; // number of track daughters
308  uint _n_pfp;
309 
310  // track information
311  float _trk_score;
312 
313  float _trk_theta;
314  float _trk_phi;
315 
316  float _trk_dir_x;
317  float _trk_dir_y;
318  float _trk_dir_z;
319 
320  float _trk_len;
321 
325 
329 
333 
334  float _trk_end_x;
335  float _trk_end_y;
336  float _trk_end_z;
337 
341 
349  float _trk_pida_y;
350 
358  float _trk_pida_u;
359 
367  float _trk_pida_v;
368 
370 
374 
375  int _longest; // longest track in slice?
376 
377  std::vector<float> _integrated_charge_u;
378  std::vector<float> _integrated_charge_v;
379  std::vector<float> _integrated_charge_y;
380 
381  std::vector<float> _allhit_charge_u;
382  std::vector<float> _allhit_charge_v;
383  std::vector<float> _allhit_charge_y;
384  std::vector<unsigned> _allhit_wire_u;
385  std::vector<unsigned> _allhit_wire_v;
386  std::vector<unsigned> _allhit_wire_y;
387  std::vector<unsigned> _allhit_channel_u;
388  std::vector<unsigned> _allhit_channel_v;
389  std::vector<unsigned> _allhit_channel_y;
390  std::vector<int> _allhit_multiplicity_u;
391  std::vector<int> _allhit_multiplicity_v;
392  std::vector<int> _allhit_multiplicity_y;
393  std::vector<float> _allhit_width_u;
394  std::vector<float> _allhit_width_v;
395  std::vector<float> _allhit_width_y;
396  std::vector<float> _allhit_time_u;
397  std::vector<float> _allhit_time_v;
398  std::vector<float> _allhit_time_y;
399  std::vector<unsigned> _allhit_nhit_u;
400  std::vector<unsigned> _allhit_nhit_v;
401  std::vector<unsigned> _allhit_nhit_y;
402 
403  std::vector<float> _trkhit_charge_u;
404  std::vector<float> _trkhit_charge_v;
405  std::vector<float> _trkhit_charge_y;
406  std::vector<unsigned> _trkhit_wire_u;
407  std::vector<unsigned> _trkhit_wire_v;
408  std::vector<unsigned> _trkhit_wire_y;
409  std::vector<unsigned> _trkhit_channel_u;
410  std::vector<unsigned> _trkhit_channel_v;
411  std::vector<unsigned> _trkhit_channel_y;
412  std::vector<int> _trkhit_multiplicity_u;
413  std::vector<int> _trkhit_multiplicity_v;
414  std::vector<int> _trkhit_multiplicity_y;
415  std::vector<float> _trkhit_width_u;
416  std::vector<float> _trkhit_width_v;
417  std::vector<float> _trkhit_width_y;
418  std::vector<float> _trkhit_time_u;
419  std::vector<float> _trkhit_time_v;
420  std::vector<float> _trkhit_time_y;
421  std::vector<unsigned> _trkhit_nhit_u;
422  std::vector<unsigned> _trkhit_nhit_v;
423  std::vector<unsigned> _trkhit_nhit_y;
424 
425  std::vector<float> _calohit_charge_u;
426  std::vector<float> _calohit_charge_v;
427  std::vector<float> _calohit_charge_y;
428  std::vector<unsigned> _calohit_wire_u;
429  std::vector<unsigned> _calohit_wire_v;
430  std::vector<unsigned> _calohit_wire_y;
431  std::vector<unsigned> _calohit_channel_u;
432  std::vector<unsigned> _calohit_channel_v;
433  std::vector<unsigned> _calohit_channel_y;
434  std::vector<int> _calohit_multiplicity_u;
435  std::vector<int> _calohit_multiplicity_v;
436  std::vector<int> _calohit_multiplicity_y;
437  std::vector<float> _calohit_width_u;
438  std::vector<float> _calohit_width_v;
439  std::vector<float> _calohit_width_y;
440  std::vector<float> _calohit_time_u;
441  std::vector<float> _calohit_time_v;
442  std::vector<float> _calohit_time_y;
443  std::vector<unsigned> _calohit_nhit_u;
444  std::vector<unsigned> _calohit_nhit_v;
445  std::vector<unsigned> _calohit_nhit_y;
446 
447  std::vector<float> _sumhit_charge_u;
448  std::vector<float> _sumhit_charge_v;
449  std::vector<float> _sumhit_charge_y;
450  std::vector<unsigned> _sumhit_wire_u;
451  std::vector<unsigned> _sumhit_wire_v;
452  std::vector<unsigned> _sumhit_wire_y;
453  std::vector<unsigned> _sumhit_channel_u;
454  std::vector<unsigned> _sumhit_channel_v;
455  std::vector<unsigned> _sumhit_channel_y;
456  std::vector<int> _sumhit_multiplicity_u;
457  std::vector<int> _sumhit_multiplicity_v;
458  std::vector<int> _sumhit_multiplicity_y;
459  std::vector<float> _sumhit_width_u;
460  std::vector<float> _sumhit_width_v;
461  std::vector<float> _sumhit_width_y;
462  std::vector<float> _sumhit_time_u;
463  std::vector<float> _sumhit_time_v;
464  std::vector<float> _sumhit_time_y;
465  std::vector<unsigned> _sumhit_nhit_u;
466  std::vector<unsigned> _sumhit_nhit_v;
467  std::vector<unsigned> _sumhit_nhit_y;
468 
469  std::vector<float> _areahit_charge_u;
470  std::vector<float> _areahit_charge_v;
471  std::vector<float> _areahit_charge_y;
472  std::vector<unsigned> _areahit_wire_u;
473  std::vector<unsigned> _areahit_wire_v;
474  std::vector<unsigned> _areahit_wire_y;
475  std::vector<unsigned> _areahit_channel_u;
476  std::vector<unsigned> _areahit_channel_v;
477  std::vector<unsigned> _areahit_channel_y;
478  std::vector<int> _areahit_multiplicity_u;
479  std::vector<int> _areahit_multiplicity_v;
480  std::vector<int> _areahit_multiplicity_y;
481  std::vector<float> _areahit_width_u;
482  std::vector<float> _areahit_width_v;
483  std::vector<float> _areahit_width_y;
484  std::vector<float> _areahit_time_u;
485  std::vector<float> _areahit_time_v;
486  std::vector<float> _areahit_time_y;
487  std::vector<unsigned> _areahit_nhit_u;
488  std::vector<unsigned> _areahit_nhit_v;
489  std::vector<unsigned> _areahit_nhit_y;
490 
491  // dedx vector
492  std::vector<float> _dqdx_u;
493  std::vector<float> _dqdx_v;
494  std::vector<float> _dqdx_y;
495 
496  std::vector<float> _dedx_u;
497  std::vector<float> _dedx_v;
498  std::vector<float> _dedx_y;
499 
500  std::vector<unsigned> _dedx_channel_u;
501  std::vector<unsigned> _dedx_channel_v;
502  std::vector<unsigned> _dedx_channel_y;
503 
504  std::vector<float> _rr_u;
505  std::vector<float> _rr_v;
506  std::vector<float> _rr_y;
507 
508  std::vector<float> _pitch_u;
509  std::vector<float> _pitch_v;
510  std::vector<float> _pitch_y;
511 
512  std::vector<float> _sx;
513  std::vector<float> _sy;
514  std::vector<float> _sz;
515 
516  std::vector<float> _w_u;
517  std::vector<float> _w_v;
518  std::vector<float> _w_y;
519 
520  std::vector<float> _t_u;
521  std::vector<float> _t_v;
522  std::vector<float> _t_y;
523 
524  std::vector<float> _x_u;
525  std::vector<float> _x_v;
526  std::vector<float> _x_y;
527 
528  std::vector<float> _y_u;
529  std::vector<float> _y_v;
530  std::vector<float> _y_y;
531 
532  std::vector<float> _z_u;
533  std::vector<float> _z_v;
534  std::vector<float> _z_y;
535 
536  std::vector<float> _dir_x_u;
537  std::vector<float> _dir_x_v;
538  std::vector<float> _dir_x_y;
539 
540  std::vector<float> _dir_y_u;
541  std::vector<float> _dir_y_v;
542  std::vector<float> _dir_y_y;
543 
544  std::vector<float> _dir_z_u;
545  std::vector<float> _dir_z_v;
546  std::vector<float> _dir_z_y;
547 };
548 
549 //----------------------------------------------------------------------------
550 /// Constructor.
551 ///
552 /// Arguments:
553 ///
554 /// pset - Fcl parameters.
555 ///
556 CalorimetryAnalysis::CalorimetryAnalysis(const fhicl::ParameterSet &p)
557  : art::EDAnalyzer{p}
558 
559 {
560  fPFPproducer = p.get< art::InputTag > ("PFPproducer","pandoraTrackGausCryo0");
561  fCALOproducer = p.get< art::InputTag > ("CALOproducer");
562  fPIDproducer = p.get< art::InputTag > ("PIDproducer" );
563  fTRKproducer = p.get< art::InputTag > ("TRKproducer" );
564  fMCSproducer = p.get<std::string>("MCSproducer", "pandoraTrackMCS");
565  fRangeproducer = p.get<std::string>("Rangeproducer", "pandoraTrackRange");
566  fT0producer = p.get< art::InputTag > ("T0producer", "" );
567  fAreaHitproducer = p.get<art::InputTag> ("AreaHitproducer", "areahit");
568  fAllTrueEnergyDeposits = p.get<bool>("AllTrueEnergyDeposits", true);
569  fHitFilterproducer = p.get<art::InputTag>("HitFilterproducer", "filtgoodhit");
570  fHitProducers = p.get<std::vector<art::InputTag>>("HitProducers");
571  fWireProducer = p.get<art::InputTag>("WireProducer", "decon1DroiTPC0");
572 
573  art::ServiceHandle<art::TFileService> tfs;
574 
575  _calo_tree = tfs->make<TTree>("CalorimetryAnalyzer", "Calo Tree");
576 
577  const geo::GeometryCore *geometry = lar::providerFrom<geo::Geometry>();
578 
579  // first the TPC volumes
580  for (auto const &cryo: geometry->IterateCryostats()) {
581  geo::GeometryCore::TPC_iterator iTPC = geometry->begin_TPC(cryo.ID()),
582  tend = geometry->end_TPC(cryo.ID());
583  std::vector<geo::BoxBoundedGeo> this_tpc_volumes;
584  while (iTPC != tend) {
585  geo::TPCGeo const& TPC = *iTPC;
586  this_tpc_volumes.push_back(TPC.ActiveBoundingBox());
587  iTPC++;
588  }
589  fTPCVolumes.push_back(std::move(this_tpc_volumes));
590  }
591 
592  // then combine them into active volumes
593  for (const std::vector<geo::BoxBoundedGeo> &tpcs: fTPCVolumes) {
594  double XMin = std::min_element(tpcs.begin(), tpcs.end(), [](auto &lhs, auto &rhs) { return lhs.MinX() < rhs.MinX(); })->MinX();
595  double YMin = std::min_element(tpcs.begin(), tpcs.end(), [](auto &lhs, auto &rhs) { return lhs.MinY() < rhs.MinY(); })->MinY();
596  double ZMin = std::min_element(tpcs.begin(), tpcs.end(), [](auto &lhs, auto &rhs) { return lhs.MinZ() < rhs.MinZ(); })->MinZ();
597 
598  double XMax = std::max_element(tpcs.begin(), tpcs.end(), [](auto &lhs, auto &rhs) { return lhs.MaxX() < rhs.MaxX(); })->MaxX();
599  double YMax = std::max_element(tpcs.begin(), tpcs.end(), [](auto &lhs, auto &rhs) { return lhs.MaxY() < rhs.MaxY(); })->MaxY();
600  double ZMax = std::max_element(tpcs.begin(), tpcs.end(), [](auto &lhs, auto &rhs) { return lhs.MaxZ() < rhs.MaxZ(); })->MaxZ();
601 
602  fActiveVolumes.emplace_back(XMin, XMax, YMin, YMax, ZMin, ZMax);
603  }
604 
605  _fileno = 0;
606 
607  setBranches(NULL);
608 }
609 
610 void CalorimetryAnalysis::analyze(art::Event const &e)
611 {
612  bool fData = e.isRealData();
613  (void) fData;
614 
615  const geo::GeometryCore *geometry = lar::providerFrom<geo::Geometry>();
616 
617  _evt = e.event();
618  _sub = e.subRun();
619  _run = e.run();
620  std::cout << "[CalorimetryAnalysis::analyzeEvent] Run: " << _run << ", SubRun: " << _sub << ", Event: "<< _evt << std::endl;
621 
622  // Build larpandora info:
623  //lar_pandora::LArPandoraHelper larpandora;
624  //lar_pandora::PFParticleVector pfparticles;
625  //lar_pandora::PFParticleMap particleMap;
626  //larpandora.CollectPFParticles(e, "pandora", pfparticles);
627  //larpandora.BuildPFParticleMap(pfparticles, particleMap);
628 
629  // recob Hits
630  std::vector<art::Ptr<recob::Hit>> hitList;
631  for (const art::InputTag &t: fHitProducers) {
632  art::ValidHandle<std::vector<recob::Hit>> hitHandle = e.getValidHandle<std::vector<recob::Hit>>(t);
633  art::fill_ptr_vector(hitList, hitHandle);
634  }
635  // recob Wires:w
636 
637  art::Handle<std::vector<recob::Wire>> wireHandle;
638  e.getByLabel(fWireProducer, wireHandle);
639 
640  std::vector<art::Ptr<recob::Wire>> wireList;
641  if (wireHandle.isValid()) {
642  art::fill_ptr_vector(wireList, wireHandle);
643  }
644 
645  // true particles
646  art::ValidHandle<std::vector<simb::MCParticle>> particleHandle = e.getValidHandle<std::vector<simb::MCParticle>>("largeant");
647  std::vector<art::Ptr<simb::MCParticle>> particleList;
648  art::fill_ptr_vector(particleList, particleHandle);
649 
650  art::ValidHandle<std::vector<sim::SimChannel>> simchannelHandle = e.getValidHandle<std::vector<sim::SimChannel>>("largeant");
651  std::vector<art::Ptr<sim::SimChannel>> simchannelList;
652  art::fill_ptr_vector(simchannelList, simchannelHandle);
653 
654  art::ValidHandle<std::vector<recob::PFParticle>> pfparticles = e.getValidHandle<std::vector<recob::PFParticle>>(fPFPproducer);
655  std::vector<art::Ptr<recob::PFParticle>> PFParticleList;
656  art::fill_ptr_vector(PFParticleList, pfparticles);
657  _n_pfp = pfparticles->size();
658 
659  art::ValidHandle<std::vector<recob::Track>> tracks = e.getValidHandle<std::vector<recob::Track>>(fTRKproducer);
660 
661  art::FindManyP<recob::SpacePoint> fmSpacePoint(PFParticleList, e, fPFPproducer);
662 
663  art::FindManyP<recob::Track> fmTracks(pfparticles, e, fTRKproducer);
664  // art::FindManyP<recob::SpacePoint> fmSpacepoints(pfparticles, e, fPFPproducer);
665  // also get hits...
666  art::FindManyP<recob::Hit> fmtrkHits(tracks, e, fTRKproducer);
667  art::FindManyP<recob::Hit> fmareaHits(tracks, e, fAreaHitproducer);
668  art::FindManyP<recob::Hit> fmcaloHits(tracks, e, fHitFilterproducer);
669 
670  art::FindManyP<anab::Calorimetry> fmCalo(tracks, e, fCALOproducer);
671  art::FindManyP<anab::ParticleID> fmPID(tracks, e, fPIDproducer);
672 
673  art::InputTag mcs_muon {fMCSproducer, "muon"};
674  art::InputTag range_muon {fRangeproducer, "muon"};
675  art::InputTag range_proton {fRangeproducer, "proton"};
676 
677  art::FindManyP<recob::MCSFitResult> fmMuonMCS(tracks, e, mcs_muon);
678  art::FindManyP<sbn::RangeP> fmMuonRange(tracks, e, range_muon);
679  art::FindManyP<sbn::RangeP> fmProtonRange(tracks, e, range_proton);
680 
681  // service data
682  auto const clock_data = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(e);
683 
684  for (art::Ptr<recob::PFParticle> p_pfp: PFParticleList) {
685  const recob::PFParticle &pfp = *p_pfp;
686 
687  fillDefault();
688 
689  // grab associated tracks
690  const std::vector<art::Ptr<recob::Track>> thisTrack = fmTracks.at(p_pfp.key());
691  if (thisTrack.size() != 1)
692  continue;
693 
694  size_t parent_ind = pfp.Parent();
695  std::cout << "Parent ind: " << parent_ind << std::endl;
696  if (parent_ind == recob::PFParticle::kPFParticlePrimary || parent_ind >= PFParticleList.size()) {
697  std::cout << "Parent doesn't exist.\n";
698  continue;
699  }
700  // check if parent is the primary
701  const recob::PFParticle *p_parent = NULL;
702  for (unsigned i_p = 0; i_p < PFParticleList.size(); i_p++) {
703  if (PFParticleList[i_p]->Self() == pfp.Parent()) {
704  p_parent = &*PFParticleList[i_p];
705  break;
706  }
707  }
708 
709  if (p_parent == NULL || !p_parent->IsPrimary()) {
710  std::cout << "Parent not primary\n";
711  continue;
712  }
713 
714  art::Ptr<recob::Track> trkPtr = thisTrack.at(0);
715  const recob::Track &track = *trkPtr;
716 
717  // get all the data
718 
719  // track data
720  std::vector<art::Ptr<recob::SpacePoint>> emptySPVector;
721  const std::vector<art::Ptr<recob::SpacePoint>> &spacepoints = fmSpacePoint.isValid() ? fmSpacePoint.at(p_pfp.key()) : emptySPVector;
722 
723  std::vector<art::Ptr<anab::Calorimetry>> emptyCaloVector;
724  const std::vector<art::Ptr<anab::Calorimetry>> &calo = fmCalo.isValid() ? fmCalo.at(trkPtr.key()) : emptyCaloVector;
725 
726  std::vector<art::Ptr<anab::ParticleID>> emptyPIDVector;
727  const std::vector<art::Ptr<anab::ParticleID>> &pid = fmPID.isValid() ? fmPID.at(trkPtr.key()) : emptyPIDVector;
728 
729  recob::MCSFitResult muon_mcs;
730  if (fmMuonMCS.isValid() && fmMuonMCS.at(trkPtr.key()).size()) muon_mcs = *fmMuonMCS.at(trkPtr.key()).at(0);
731 
732  sbn::RangeP muon_range;
733  if (fmMuonRange.isValid() && fmMuonRange.at(trkPtr.key()).size()) muon_range = *fmMuonRange.at(trkPtr.key()).at(0);
734 
735  sbn::RangeP proton_range;
736  if (fmProtonRange.isValid() && fmProtonRange.at(trkPtr.key()).size()) proton_range = *fmProtonRange.at(trkPtr.key()).at(0);
737 
738  std::vector<art::Ptr<recob::Hit>> emptyHitVector;
739  const std::vector<art::Ptr<recob::Hit>> &trkHits = fmtrkHits.isValid() ? fmtrkHits.at(trkPtr.key()) : emptyHitVector;
740  const std::vector<art::Ptr<recob::Hit>> &areaHits = fmareaHits.isValid() ? fmareaHits.at(trkPtr.key()) : emptyHitVector;
741  const std::vector<art::Ptr<recob::Hit>> &caloHits = fmcaloHits.isValid() ? fmcaloHits.at(trkPtr.key()) : emptyHitVector;
742 
743  // Get the true matching MC particle
744  std::vector<std::pair<int, float>> matches = CAFRecoUtils::AllTrueParticleIDEnergyMatches(clock_data, trkHits, true);
745  // get the match with the most energy
746  int match_id = matches.size() ? std::max_element(matches.begin(), matches.end(),
747  [](const auto &a, const auto &b) { return a.second < b.second; })->first : -1;
748  float matchE = matches.size() ? std::max_element(matches.begin(), matches.end(),
749  [](const auto &a, const auto &b) { return a.second < b.second; })->second : -1;
750  art::Ptr<simb::MCParticle> true_particle;
751  for (art::Ptr<simb::MCParticle> p: particleList) {
752  if (p->TrackId() == match_id) {
753  true_particle = p;
754  break;
755  }
756  }
757  float trueTrackE = 0.;
758  for (auto pair: matches) trueTrackE += pair.second;
759 
760  // TODO: fix??
761  //
762  // ignore tracks with no match
763  if (!true_particle) continue;
764  // only take particle that matches to true instigator
765  if (true_particle->Process() != "primary") continue;
766 
767 
768  std::cout << "Track: " << track.ID() << " len: " << track.Length() << " matched to particle: " << true_particle->TrackId() << " frac: " << (matchE/trueTrackE) << std::endl;
769 
770  art::ServiceHandle<cheat::BackTrackerService> bt_serv;
771 
772  std::array<std::map<unsigned, std::vector<const sim::IDE*>>, 3> particle_ide_map;
773  for (const art::Ptr<sim::SimChannel> sc: simchannelList) {
774  for (const auto &pair: sc->TDCIDEMap()) {
775  for (const sim::IDE &ide: pair.second) {
776  if (ide.trackID == true_particle->TrackId() || fAllTrueEnergyDeposits) {
777  unsigned plane_id = geometry->ChannelToWire(sc->Channel()).at(0).Plane;
778  particle_ide_map[plane_id][sc->Channel()].push_back(&ide);
779  }
780  }
781  }
782  }
783 
784  std::array<std::vector<const sim::IDE*>, 3> allIDEs;
785  for (unsigned i = 0; i < particleList.size(); i++) {
786  int G4ID = particleList[i]->TrackId();
787  for (unsigned plane = 0; plane < 3; plane++) {
788  // build the plane ID
789  geo::PlaneID plane_id(0, 0, plane);
790  std::vector<const sim::IDE*> this_ides = bt_serv->TrackIdToSimIDEs_Ps(G4ID, geometry->View(plane_id));
791  allIDEs[plane].insert(allIDEs[plane].end(), this_ides.begin(), this_ides.end());
792  }
793  }
794 
795  FillCalorimetry(e,
796  wireList,
797  hitList,
798  p_pfp,
799  thisTrack.at(0),
800  spacepoints,
801  calo,
802  pid,
803  areaHits,
804  trkHits,
805  caloHits,
806  muon_mcs,
807  muon_range,
808  proton_range,
809  false,
810  matches,
811  true_particle,
812  particle_ide_map,
813  allIDEs,
815 
816  }// for all PFParticles
817 }// analyzeEvent
818 
820 {
821  // backtracking information
822  _backtracked_pdg = std::numeric_limits<int>::lowest(); // PDG code of backtracked particle
823  _backtracked_e = std::numeric_limits<float>::lowest(); // energy of backtracked particle
824  _backtracked_deposited_e_u = std::numeric_limits<float>::lowest(); // energy of backtracked particle
825  _backtracked_deposited_e_v = std::numeric_limits<float>::lowest(); // energy of backtracked particle
826  _backtracked_deposited_e_y = std::numeric_limits<float>::lowest(); // energy of backtracked particle
827  _backtracked_q_u = std::numeric_limits<float>::lowest();
828  _backtracked_q_v = std::numeric_limits<float>::lowest();
829  _backtracked_q_y = std::numeric_limits<float>::lowest();
830  _backtracked_qtotal_u = std::numeric_limits<float>::lowest();
831  _backtracked_qtotal_v = std::numeric_limits<float>::lowest();
832  _backtracked_qtotal_y = std::numeric_limits<float>::lowest();
833  _backtracked_purity = std::numeric_limits<float>::lowest(); // purity of backtracking
834  _backtracked_completeness = std::numeric_limits<float>::lowest(); // completeness of backtracking
835  _backtracked_overlay_purity = std::numeric_limits<float>::lowest(); // purity of overlay
837  _backtracked_end_in_tpc = false;
838 
839  _backtracked_pc_q_u.clear();
840  _backtracked_pc_q_v.clear();
841  _backtracked_pc_q_y.clear();
842 
843  _backtracked_pc_e_u.clear();
844  _backtracked_pc_e_v.clear();
845  _backtracked_pc_e_y.clear();
846 
847  _backtracked_c_u.clear();
848  _backtracked_c_v.clear();
849  _backtracked_c_y.clear();
850 
851  _backtracked_nloc_c_u.clear();
852  _backtracked_locx_c_u.clear();
853  _backtracked_locy_c_u.clear();
854  _backtracked_locz_c_u.clear();
855  _backtracked_dirx_c_u.clear();
856  _backtracked_diry_c_u.clear();
857  _backtracked_dirz_c_u.clear();
858  _backtracked_de_c_u.clear();
859  _backtracked_pitch_c_u.clear();
861 
862  _backtracked_nloc_c_v.clear();
863  _backtracked_locx_c_v.clear();
864  _backtracked_locy_c_v.clear();
865  _backtracked_locz_c_v.clear();
866  _backtracked_dirx_c_v.clear();
867  _backtracked_diry_c_v.clear();
868  _backtracked_dirz_c_v.clear();
869  _backtracked_de_c_v.clear();
870  _backtracked_pitch_c_v.clear();
872 
873  _backtracked_nloc_c_y.clear();
874  _backtracked_locx_c_y.clear();
875  _backtracked_locy_c_y.clear();
876  _backtracked_locz_c_y.clear();
877  _backtracked_dirx_c_y.clear();
878  _backtracked_diry_c_y.clear();
879  _backtracked_dirz_c_y.clear();
880  _backtracked_de_c_y.clear();
881  _backtracked_pitch_c_y.clear();
883 
884  _backtracked_x.clear();
885  _backtracked_y.clear();
886  _backtracked_z.clear();
887 
888  _backtracked_dirx.clear();
889  _backtracked_diry.clear();
890  _backtracked_dirz.clear();
891 
892  _backtracked_length = std::numeric_limits<float>::lowest();
893  _backtracked_length_start_to_end = std::numeric_limits<float>::lowest();
894 
895  _backtracked_theta = std::numeric_limits<float>::lowest();
896  _backtracked_phi = std::numeric_limits<float>::lowest();
897 
898  _backtracked_px = std::numeric_limits<float>::lowest();
899  _backtracked_py = std::numeric_limits<float>::lowest();
900  _backtracked_pz = std::numeric_limits<float>::lowest();
901 
902  _backtracked_end_x = std::numeric_limits<float>::lowest();
903  _backtracked_end_y = std::numeric_limits<float>::lowest();
904  _backtracked_end_z = std::numeric_limits<float>::lowest();
905 
906  _backtracked_start_x = std::numeric_limits<float>::lowest();
907  _backtracked_start_y = std::numeric_limits<float>::lowest();
908  _backtracked_start_z = std::numeric_limits<float>::lowest();
909  _backtracked_start_t = std::numeric_limits<float>::lowest();
910  _backtracked_start_U = std::numeric_limits<float>::lowest();
911  _backtracked_start_V = std::numeric_limits<float>::lowest();
912  _backtracked_start_Y = std::numeric_limits<float>::lowest();
913  _backtracked_sce_start_x = std::numeric_limits<float>::lowest();
914  _backtracked_sce_start_y = std::numeric_limits<float>::lowest();
915  _backtracked_sce_start_z = std::numeric_limits<float>::lowest();
916  _backtracked_sce_start_U = std::numeric_limits<float>::lowest();
917  _backtracked_sce_start_V = std::numeric_limits<float>::lowest();
918  _backtracked_sce_start_Y = std::numeric_limits<float>::lowest();
919 
920  _generation = std::numeric_limits<uint>::lowest();
921  _shr_daughters = std::numeric_limits<uint>::lowest();
922  _trk_daughters = std::numeric_limits<uint>::lowest();
923  _daughters = std::numeric_limits<uint>::lowest();
924 
925  // track information
926  _trk_score = std::numeric_limits<float>::lowest();
927 
928  _trk_theta = std::numeric_limits<float>::lowest();
929  _trk_phi = std::numeric_limits<float>::lowest();
930  _trk_len = std::numeric_limits<float>::lowest();
931 
932  _trk_calo_range_u = std::numeric_limits<float>::lowest();
933  _trk_calo_range_v = std::numeric_limits<float>::lowest();
934  _trk_calo_range_y = std::numeric_limits<float>::lowest();
935 
936  _trk_dir_x = std::numeric_limits<float>::lowest();
937  _trk_dir_y = std::numeric_limits<float>::lowest();
938  _trk_dir_z = std::numeric_limits<float>::lowest();
939 
940  _trk_start_x = std::numeric_limits<float>::lowest();
941  _trk_start_y = std::numeric_limits<float>::lowest();
942  _trk_start_z = std::numeric_limits<float>::lowest();
943 
944  _trk_sce_start_x = std::numeric_limits<float>::lowest();
945  _trk_sce_start_y = std::numeric_limits<float>::lowest();
946  _trk_sce_start_z = std::numeric_limits<float>::lowest();
947 
948  _trk_end_x = std::numeric_limits<float>::lowest();
949  _trk_end_y = std::numeric_limits<float>::lowest();
950  _trk_end_z = std::numeric_limits<float>::lowest();
951 
952  _trk_sce_end_x = std::numeric_limits<float>::lowest();
953  _trk_sce_end_y = std::numeric_limits<float>::lowest();
954  _trk_sce_end_z = std::numeric_limits<float>::lowest();
955 
956  _trk_bragg_p_y = std::numeric_limits<float>::lowest();
957  _trk_bragg_mu_y = std::numeric_limits<float>::lowest();
958  _trk_bragg_mip_y = std::numeric_limits<float>::lowest();
959  _trk_pid_chipr_y = std::numeric_limits<float>::lowest();
960  _trk_pid_chika_y = std::numeric_limits<float>::lowest();
961  _trk_pid_chipi_y = std::numeric_limits<float>::lowest();
962  _trk_pid_chimu_y = std::numeric_limits<float>::lowest();
963  _trk_pida_y = std::numeric_limits<float>::lowest();
964 
965  _trk_bragg_p_u = std::numeric_limits<float>::lowest();
966  _trk_bragg_mu_u = std::numeric_limits<float>::lowest();
967  _trk_bragg_mip_u = std::numeric_limits<float>::lowest();
968  _trk_pid_chipr_u = std::numeric_limits<float>::lowest();
969  _trk_pid_chika_u = std::numeric_limits<float>::lowest();
970  _trk_pid_chipi_u = std::numeric_limits<float>::lowest();
971  _trk_pid_chimu_u = std::numeric_limits<float>::lowest();
972  _trk_pida_u = std::numeric_limits<float>::lowest();
973 
974  _trk_bragg_p_v = std::numeric_limits<float>::lowest();
975  _trk_bragg_mu_v = std::numeric_limits<float>::lowest();
976  _trk_bragg_mip_v = std::numeric_limits<float>::lowest();
977  _trk_pid_chipr_v = std::numeric_limits<float>::lowest();
978  _trk_pid_chika_v = std::numeric_limits<float>::lowest();
979  _trk_pid_chipi_v = std::numeric_limits<float>::lowest();
980  _trk_pid_chimu_v = std::numeric_limits<float>::lowest();
981  _trk_pida_v = std::numeric_limits<float>::lowest();
982 
983  _trk_bragg_p_three_planes = std::numeric_limits<float>::lowest();
984 
985  _longest = std::numeric_limits<int>::lowest();
986 
987  _trk_mcs_muon_mom = std::numeric_limits<float>::lowest();
988  _trk_energy_proton = std::numeric_limits<float>::lowest();
989  _trk_energy_muon = std::numeric_limits<float>::lowest();
990 
991 
992  _integrated_charge_u.clear();
993  _integrated_charge_v.clear();
994  _integrated_charge_y.clear();
995 
996  _trkhit_charge_u.clear();
997  _trkhit_charge_v.clear();
998  _trkhit_charge_y.clear();
999  _trkhit_wire_u.clear();
1000  _trkhit_wire_v.clear();
1001  _trkhit_wire_y.clear();
1002  _trkhit_channel_u.clear();
1003  _trkhit_channel_v.clear();
1004  _trkhit_channel_y.clear();
1005  _trkhit_multiplicity_u.clear();
1006  _trkhit_multiplicity_v.clear();
1007  _trkhit_multiplicity_y.clear();
1008  _trkhit_width_u.clear();
1009  _trkhit_width_v.clear();
1010  _trkhit_width_y.clear();
1011  _trkhit_time_u.clear();
1012  _trkhit_time_v.clear();
1013  _trkhit_time_y.clear();
1014  _trkhit_nhit_u.clear();
1015  _trkhit_nhit_v.clear();
1016  _trkhit_nhit_y.clear();
1017 
1018  _areahit_charge_u.clear();
1019  _areahit_charge_v.clear();
1020  _areahit_charge_y.clear();
1021  _areahit_wire_u.clear();
1022  _areahit_wire_v.clear();
1023  _areahit_wire_y.clear();
1024  _areahit_channel_u.clear();
1025  _areahit_channel_v.clear();
1026  _areahit_channel_y.clear();
1027  _areahit_multiplicity_u.clear();
1028  _areahit_multiplicity_v.clear();
1029  _areahit_multiplicity_y.clear();
1030  _areahit_width_u.clear();
1031  _areahit_width_v.clear();
1032  _areahit_width_y.clear();
1033  _areahit_time_u.clear();
1034  _areahit_time_v.clear();
1035  _areahit_time_y.clear();
1036  _areahit_nhit_u.clear();
1037  _areahit_nhit_v.clear();
1038  _areahit_nhit_y.clear();
1039 
1040  _allhit_charge_u.clear();
1041  _allhit_charge_v.clear();
1042  _allhit_charge_y.clear();
1043  _allhit_wire_u.clear();
1044  _allhit_wire_v.clear();
1045  _allhit_wire_y.clear();
1046  _allhit_channel_u.clear();
1047  _allhit_channel_v.clear();
1048  _allhit_channel_y.clear();
1049  _allhit_multiplicity_u.clear();
1050  _allhit_multiplicity_v.clear();
1051  _allhit_multiplicity_y.clear();
1052  _allhit_width_u.clear();
1053  _allhit_width_v.clear();
1054  _allhit_width_y.clear();
1055  _allhit_time_u.clear();
1056  _allhit_time_v.clear();
1057  _allhit_time_y.clear();
1058  _allhit_nhit_u.clear();
1059  _allhit_nhit_v.clear();
1060  _allhit_nhit_y.clear();
1061 
1062  _calohit_charge_u.clear();
1063  _calohit_charge_v.clear();
1064  _calohit_charge_y.clear();
1065  _calohit_wire_u.clear();
1066  _calohit_wire_v.clear();
1067  _calohit_wire_y.clear();
1068  _calohit_channel_u.clear();
1069  _calohit_channel_v.clear();
1070  _calohit_channel_y.clear();
1071  _calohit_multiplicity_u.clear();
1072  _calohit_multiplicity_v.clear();
1073  _calohit_multiplicity_y.clear();
1074  _calohit_width_u.clear();
1075  _calohit_width_v.clear();
1076  _calohit_width_y.clear();
1077  _calohit_time_u.clear();
1078  _calohit_time_v.clear();
1079  _calohit_time_y.clear();
1080  _calohit_nhit_u.clear();
1081  _calohit_nhit_v.clear();
1082  _calohit_nhit_y.clear();
1083 
1084  _sumhit_charge_u.clear();
1085  _sumhit_charge_v.clear();
1086  _sumhit_charge_y.clear();
1087  _sumhit_wire_u.clear();
1088  _sumhit_wire_v.clear();
1089  _sumhit_wire_y.clear();
1090  _sumhit_channel_u.clear();
1091  _sumhit_channel_v.clear();
1092  _sumhit_channel_y.clear();
1093  _sumhit_multiplicity_u.clear();
1094  _sumhit_multiplicity_v.clear();
1095  _sumhit_multiplicity_y.clear();
1096  _sumhit_width_u.clear();
1097  _sumhit_width_v.clear();
1098  _sumhit_width_y.clear();
1099  _sumhit_time_u.clear();
1100  _sumhit_time_v.clear();
1101  _sumhit_time_y.clear();
1102  _sumhit_nhit_u.clear();
1103  _sumhit_nhit_v.clear();
1104  _sumhit_nhit_y.clear();
1105 
1106  // dedx vector
1107  _dqdx_u.clear();
1108  _dqdx_v.clear();
1109  _dqdx_y.clear();
1110 
1111  _dedx_u.clear();
1112  _dedx_v.clear();
1113  _dedx_y.clear();
1114 
1115  _dedx_channel_u.clear();
1116  _dedx_channel_v.clear();
1117  _dedx_channel_y.clear();
1118 
1119  _rr_u.clear();
1120  _rr_v.clear();
1121  _rr_y.clear();
1122 
1123  _pitch_u.clear();
1124  _pitch_v.clear();
1125  _pitch_y.clear();
1126 
1127  _sx.clear();
1128  _sy.clear();
1129  _sz.clear();
1130 
1131  _w_u.clear();
1132  _w_v.clear();
1133  _w_y.clear();
1134 
1135  _t_u.clear();
1136  _t_v.clear();
1137  _t_y.clear();
1138 
1139  _x_u.clear();
1140  _x_v.clear();
1141  _x_y.clear();
1142 
1143  _y_u.clear();
1144  _y_v.clear();
1145  _y_y.clear();
1146 
1147  _z_u.clear();
1148  _z_v.clear();
1149  _z_y.clear();
1150 
1151  _dir_x_u.clear();
1152  _dir_x_v.clear();
1153  _dir_x_y.clear();
1154 
1155  _dir_y_u.clear();
1156  _dir_y_v.clear();
1157  _dir_y_y.clear();
1158 
1159  _dir_z_u.clear();
1160  _dir_z_v.clear();
1161  _dir_z_y.clear();
1162 }
1163 
1165 {
1166  _calo_tree->Branch("fileno", &_fileno, "fileno/i");
1167  _calo_tree->Branch("run", &_run, "run/i");
1168  _calo_tree->Branch("sub", &_sub, "sub/i");
1169  _calo_tree->Branch("evt", &_evt, "evt/i");
1170  _calo_tree->Branch("pfpno", &_pfpno, "pfpno/i");
1171  _calo_tree->Branch("trkid", &_trkid, "trkid/i");
1172 
1173  // backtracking information
1174  _calo_tree->Branch("backtracked_pdg", &_backtracked_pdg, "backtracked_pdg/I"); // PDG code of backtracked particle
1175  _calo_tree->Branch("backtracked_e", &_backtracked_e, "backtracked_e/F"); // energy of backtracked particle
1176  _calo_tree->Branch("backtracked_deposited_e_u", &_backtracked_deposited_e_u, "backtracked_deposited_e_u/F"); // energy of backtracked particle
1177  _calo_tree->Branch("backtracked_deposited_e_v", &_backtracked_deposited_e_v, "backtracked_deposited_e_v/F"); // energy of backtracked particle
1178  _calo_tree->Branch("backtracked_deposited_e_y", &_backtracked_deposited_e_y, "backtracked_deposited_e_y/F"); // energy of backtracked particle
1179  _calo_tree->Branch("backtracked_q_u", &_backtracked_q_u, "backtracked_q_u/F"); // energy of backtracked particle
1180  _calo_tree->Branch("backtracked_q_v", &_backtracked_q_v, "backtracked_q_v/F"); // energy of backtracked particle
1181  _calo_tree->Branch("backtracked_q_y", &_backtracked_q_y, "backtracked_q_y/F"); // energy of backtracked particle
1182  _calo_tree->Branch("backtracked_qtotal_u", &_backtracked_qtotal_u, "backtracked_qtotal_u/F"); // energy of backtracked particle
1183  _calo_tree->Branch("backtracked_qtotal_v", &_backtracked_qtotal_v, "backtracked_qtotal_v/F"); // energy of backtracked particle
1184  _calo_tree->Branch("backtracked_qtotal_y", &_backtracked_qtotal_y, "backtracked_qtotal_y/F"); // energy of backtracked particle
1185 
1186  _calo_tree->Branch("backtracked_pc_q_u", "std::vector<float>", &_backtracked_pc_q_u);
1187  _calo_tree->Branch("backtracked_pc_q_v", "std::vector<float>", &_backtracked_pc_q_v);
1188  _calo_tree->Branch("backtracked_pc_q_y", "std::vector<float>", &_backtracked_pc_q_y);
1189 
1190  _calo_tree->Branch("backtracked_pc_e_u", "std::vector<float>", &_backtracked_pc_e_u);
1191  _calo_tree->Branch("backtracked_pc_e_v", "std::vector<float>", &_backtracked_pc_e_v);
1192  _calo_tree->Branch("backtracked_pc_e_y", "std::vector<float>", &_backtracked_pc_e_y);
1193 
1194  _calo_tree->Branch("backtracked_c_u", "std::vector<unsigned>", &_backtracked_c_u);
1195  _calo_tree->Branch("backtracked_c_v", "std::vector<unsigned>", &_backtracked_c_v);
1196  _calo_tree->Branch("backtracked_c_y", "std::vector<unsigned>", &_backtracked_c_y);
1197 
1198  _calo_tree->Branch("backtracked_nloc_c_u", "std::vector<int>", &_backtracked_nloc_c_u);
1199  _calo_tree->Branch("backtracked_locx_c_u", "std::vector<float>", &_backtracked_locx_c_u);
1200  _calo_tree->Branch("backtracked_locy_c_u", "std::vector<float>", &_backtracked_locy_c_u);
1201  _calo_tree->Branch("backtracked_locz_c_u", "std::vector<float>", &_backtracked_locz_c_u);
1202  _calo_tree->Branch("backtracked_dirx_c_u", "std::vector<float>", &_backtracked_dirx_c_u);
1203  _calo_tree->Branch("backtracked_diry_c_u", "std::vector<float>", &_backtracked_diry_c_u);
1204  _calo_tree->Branch("backtracked_dirz_c_u", "std::vector<float>", &_backtracked_dirz_c_u);
1205  _calo_tree->Branch("backtracked_de_c_u", "std::vector<float>", &_backtracked_de_c_u);
1206  _calo_tree->Branch("backtracked_pitch_c_u", "std::vector<float>", &_backtracked_pitch_c_u);
1207  _calo_tree->Branch("backtracked_scepitch_c_u", "std::vector<float>", &_backtracked_scepitch_c_u);
1208 
1209  _calo_tree->Branch("backtracked_nloc_c_v", "std::vector<int>", &_backtracked_nloc_c_v);
1210  _calo_tree->Branch("backtracked_locx_c_v", "std::vector<float>", &_backtracked_locx_c_v);
1211  _calo_tree->Branch("backtracked_locy_c_v", "std::vector<float>", &_backtracked_locy_c_v);
1212  _calo_tree->Branch("backtracked_locz_c_v", "std::vector<float>", &_backtracked_locz_c_v);
1213  _calo_tree->Branch("backtracked_dirx_c_v", "std::vector<float>", &_backtracked_dirx_c_v);
1214  _calo_tree->Branch("backtracked_diry_c_v", "std::vector<float>", &_backtracked_diry_c_v);
1215  _calo_tree->Branch("backtracked_dirz_c_v", "std::vector<float>", &_backtracked_dirz_c_v);
1216  _calo_tree->Branch("backtracked_de_c_v", "std::vector<float>", &_backtracked_de_c_v);
1217  _calo_tree->Branch("backtracked_pitch_c_v", "std::vector<float>", &_backtracked_pitch_c_v);
1218  _calo_tree->Branch("backtracked_scepitch_c_v", "std::vector<float>", &_backtracked_scepitch_c_v);
1219 
1220  _calo_tree->Branch("backtracked_nloc_c_y", "std::vector<int>", &_backtracked_nloc_c_y);
1221  _calo_tree->Branch("backtracked_locx_c_y", "std::vector<float>", &_backtracked_locx_c_y);
1222  _calo_tree->Branch("backtracked_locy_c_y", "std::vector<float>", &_backtracked_locy_c_y);
1223  _calo_tree->Branch("backtracked_locz_c_y", "std::vector<float>", &_backtracked_locz_c_y);
1224  _calo_tree->Branch("backtracked_dirx_c_y", "std::vector<float>", &_backtracked_dirx_c_y);
1225  _calo_tree->Branch("backtracked_diry_c_y", "std::vector<float>", &_backtracked_diry_c_y);
1226  _calo_tree->Branch("backtracked_dirz_c_y", "std::vector<float>", &_backtracked_dirz_c_y);
1227  _calo_tree->Branch("backtracked_de_c_y", "std::vector<float>", &_backtracked_de_c_y);
1228  _calo_tree->Branch("backtracked_pitch_c_y", "std::vector<float>", &_backtracked_pitch_c_y);
1229  _calo_tree->Branch("backtracked_scepitch_c_y", "std::vector<float>", &_backtracked_scepitch_c_y);
1230 
1231  _calo_tree->Branch("backtracked_x", "std::vector<float>", &_backtracked_x);
1232  _calo_tree->Branch("backtracked_y", "std::vector<float>", &_backtracked_y);
1233  _calo_tree->Branch("backtracked_z", "std::vector<float>", &_backtracked_z);
1234 
1235  _calo_tree->Branch("backtracked_dirx", "std::vector<float>", &_backtracked_dirx);
1236  _calo_tree->Branch("backtracked_diry", "std::vector<float>", &_backtracked_diry);
1237  _calo_tree->Branch("backtracked_dirz", "std::vector<float>", &_backtracked_dirz);
1238 
1239  _calo_tree->Branch("backtracked_theta", &_backtracked_theta, "backtracked_theta/F");
1240  _calo_tree->Branch("backtracked_phi", &_backtracked_phi, "backtracked_phi/F");
1241 
1242  _calo_tree->Branch("backtracked_px", &_backtracked_px, "backtracked_px/F");
1243  _calo_tree->Branch("backtracked_py", &_backtracked_py, "backtracked_py/F");
1244  _calo_tree->Branch("backtracked_pz", &_backtracked_pz, "backtracked_pz/F");
1245 
1246  _calo_tree->Branch("backtracked_length", &_backtracked_length,"backtracked_length/F");
1247  _calo_tree->Branch("backtracked_length_start_to_end", &_backtracked_length_start_to_end, "backtracked_length_start_to_end/F");
1248 
1249  _calo_tree->Branch("backtracked_purity", &_backtracked_purity, "backtracked_purity/F"); // purity of backtracking
1250  _calo_tree->Branch("backtracked_completeness", &_backtracked_completeness, "backtracked_completeness/F"); // completeness of backtracking
1251  _calo_tree->Branch("backtracked_overlay_purity", &_backtracked_overlay_purity, "backtracked_overlay_purity/F"); // purity of overlay
1252 
1253  _calo_tree->Branch("integrated_charge_u", "std::vector<float>", &_integrated_charge_u);
1254  _calo_tree->Branch("integrated_charge_v", "std::vector<float>", &_integrated_charge_v);
1255  _calo_tree->Branch("integrated_charge_y", "std::vector<float>", &_integrated_charge_y);
1256 
1257  _calo_tree->Branch("areahit_charge_u", "std::vector<float>", &_areahit_charge_u);
1258  _calo_tree->Branch("areahit_charge_v", "std::vector<float>", &_areahit_charge_v);
1259  _calo_tree->Branch("areahit_charge_y", "std::vector<float>", &_areahit_charge_y);
1260  _calo_tree->Branch("areahit_wire_u", "std::vector<unsigned>", &_areahit_wire_u);
1261  _calo_tree->Branch("areahit_wire_v", "std::vector<unsigned>", &_areahit_wire_v);
1262  _calo_tree->Branch("areahit_wire_y", "std::vector<unsigned>", &_areahit_wire_y);
1263  _calo_tree->Branch("areahit_channel_u", "std::vector<unsigned>", &_areahit_channel_u);
1264  _calo_tree->Branch("areahit_channel_v", "std::vector<unsigned>", &_areahit_channel_v);
1265  _calo_tree->Branch("areahit_channel_y", "std::vector<unsigned>", &_areahit_channel_y);
1266  _calo_tree->Branch("areahit_multiplicity_u", "std::vector<int>", &_areahit_multiplicity_u);
1267  _calo_tree->Branch("areahit_multiplicity_v", "std::vector<int>", &_areahit_multiplicity_v);
1268  _calo_tree->Branch("areahit_multiplicity_y", "std::vector<int>", &_areahit_multiplicity_y);
1269  _calo_tree->Branch("areahit_width_u", "std::vector<float>", &_areahit_width_u);
1270  _calo_tree->Branch("areahit_width_v", "std::vector<float>", &_areahit_width_v);
1271  _calo_tree->Branch("areahit_width_y", "std::vector<float>", &_areahit_width_y);
1272  _calo_tree->Branch("areahit_time_u", "std::vector<float>", &_areahit_time_u);
1273  _calo_tree->Branch("areahit_time_v", "std::vector<float>", &_areahit_time_v);
1274  _calo_tree->Branch("areahit_time_y", "std::vector<float>", &_areahit_time_y);
1275  _calo_tree->Branch("areahit_nhit_u", "std::vector<unsigned>", &_areahit_nhit_u);
1276  _calo_tree->Branch("areahit_nhit_v", "std::vector<unsigned>", &_areahit_nhit_v);
1277  _calo_tree->Branch("areahit_nhit_y", "std::vector<unsigned>", &_areahit_nhit_y);
1278 
1279  _calo_tree->Branch("allhit_charge_u", "std::vector<float>", &_allhit_charge_u);
1280  _calo_tree->Branch("allhit_charge_v", "std::vector<float>", &_allhit_charge_v);
1281  _calo_tree->Branch("allhit_charge_y", "std::vector<float>", &_allhit_charge_y);
1282  _calo_tree->Branch("allhit_wire_u", "std::vector<unsigned>", &_allhit_wire_u);
1283  _calo_tree->Branch("allhit_wire_v", "std::vector<unsigned>", &_allhit_wire_v);
1284  _calo_tree->Branch("allhit_wire_y", "std::vector<unsigned>", &_allhit_wire_y);
1285  _calo_tree->Branch("allhit_channel_u", "std::vector<unsigned>", &_allhit_channel_u);
1286  _calo_tree->Branch("allhit_channel_v", "std::vector<unsigned>", &_allhit_channel_v);
1287  _calo_tree->Branch("allhit_channel_y", "std::vector<unsigned>", &_allhit_channel_y);
1288  _calo_tree->Branch("allhit_multiplicity_u", "std::vector<int>", &_allhit_multiplicity_u);
1289  _calo_tree->Branch("allhit_multiplicity_v", "std::vector<int>", &_allhit_multiplicity_v);
1290  _calo_tree->Branch("allhit_multiplicity_y", "std::vector<int>", &_allhit_multiplicity_y);
1291  _calo_tree->Branch("allhit_width_u", "std::vector<float>", &_allhit_width_u);
1292  _calo_tree->Branch("allhit_width_v", "std::vector<float>", &_allhit_width_v);
1293  _calo_tree->Branch("allhit_width_y", "std::vector<float>", &_allhit_width_y);
1294  _calo_tree->Branch("allhit_time_u", "std::vector<float>", &_allhit_time_u);
1295  _calo_tree->Branch("allhit_time_v", "std::vector<float>", &_allhit_time_v);
1296  _calo_tree->Branch("allhit_time_y", "std::vector<float>", &_allhit_time_y);
1297  _calo_tree->Branch("allhit_nhit_u", "std::vector<unsigned>", &_allhit_nhit_u);
1298  _calo_tree->Branch("allhit_nhit_v", "std::vector<unsigned>", &_allhit_nhit_v);
1299  _calo_tree->Branch("allhit_nhit_y", "std::vector<unsigned>", &_allhit_nhit_y);
1300 
1301  _calo_tree->Branch("trkhit_charge_u", "std::vector<float>", &_trkhit_charge_u);
1302  _calo_tree->Branch("trkhit_charge_v", "std::vector<float>", &_trkhit_charge_v);
1303  _calo_tree->Branch("trkhit_charge_y", "std::vector<float>", &_trkhit_charge_y);
1304  _calo_tree->Branch("trkhit_wire_u", "std::vector<unsigned>", &_trkhit_wire_u);
1305  _calo_tree->Branch("trkhit_wire_v", "std::vector<unsigned>", &_trkhit_wire_v);
1306  _calo_tree->Branch("trkhit_wire_y", "std::vector<unsigned>", &_trkhit_wire_y);
1307  _calo_tree->Branch("trkhit_channel_u", "std::vector<unsigned>", &_trkhit_channel_u);
1308  _calo_tree->Branch("trkhit_channel_v", "std::vector<unsigned>", &_trkhit_channel_v);
1309  _calo_tree->Branch("trkhit_channel_y", "std::vector<unsigned>", &_trkhit_channel_y);
1310  _calo_tree->Branch("trkhit_multiplicity_u", "std::vector<int>", &_trkhit_multiplicity_u);
1311  _calo_tree->Branch("trkhit_multiplicity_v", "std::vector<int>", &_trkhit_multiplicity_v);
1312  _calo_tree->Branch("trkhit_multiplicity_y", "std::vector<int>", &_trkhit_multiplicity_y);
1313  _calo_tree->Branch("trkhit_width_u", "std::vector<float>", &_trkhit_width_u);
1314  _calo_tree->Branch("trkhit_width_v", "std::vector<float>", &_trkhit_width_v);
1315  _calo_tree->Branch("trkhit_width_y", "std::vector<float>", &_trkhit_width_y);
1316  _calo_tree->Branch("trkhit_time_u", "std::vector<float>", &_trkhit_time_u);
1317  _calo_tree->Branch("trkhit_time_v", "std::vector<float>", &_trkhit_time_v);
1318  _calo_tree->Branch("trkhit_time_y", "std::vector<float>", &_trkhit_time_y);
1319  _calo_tree->Branch("trkhit_nhit_u", "std::vector<unsigned>", &_trkhit_nhit_u);
1320  _calo_tree->Branch("trkhit_nhit_v", "std::vector<unsigned>", &_trkhit_nhit_v);
1321  _calo_tree->Branch("trkhit_nhit_y", "std::vector<unsigned>", &_trkhit_nhit_y);
1322 
1323  _calo_tree->Branch("calohit_charge_u", "std::vector<float>", &_calohit_charge_u);
1324  _calo_tree->Branch("calohit_charge_v", "std::vector<float>", &_calohit_charge_v);
1325  _calo_tree->Branch("calohit_charge_y", "std::vector<float>", &_calohit_charge_y);
1326  _calo_tree->Branch("calohit_wire_u", "std::vector<unsigned>", &_calohit_wire_u);
1327  _calo_tree->Branch("calohit_wire_v", "std::vector<unsigned>", &_calohit_wire_v);
1328  _calo_tree->Branch("calohit_wire_y", "std::vector<unsigned>", &_calohit_wire_y);
1329  _calo_tree->Branch("calohit_channel_u", "std::vector<unsigned>", &_calohit_channel_u);
1330  _calo_tree->Branch("calohit_channel_v", "std::vector<unsigned>", &_calohit_channel_v);
1331  _calo_tree->Branch("calohit_channel_y", "std::vector<unsigned>", &_calohit_channel_y);
1332  _calo_tree->Branch("calohit_multiplicity_u", "std::vector<int>", &_calohit_multiplicity_u);
1333  _calo_tree->Branch("calohit_multiplicity_v", "std::vector<int>", &_calohit_multiplicity_v);
1334  _calo_tree->Branch("calohit_multiplicity_y", "std::vector<int>", &_calohit_multiplicity_y);
1335  _calo_tree->Branch("calohit_width_u", "std::vector<float>", &_calohit_width_u);
1336  _calo_tree->Branch("calohit_width_v", "std::vector<float>", &_calohit_width_v);
1337  _calo_tree->Branch("calohit_width_y", "std::vector<float>", &_calohit_width_y);
1338  _calo_tree->Branch("calohit_time_u", "std::vector<float>", &_calohit_time_u);
1339  _calo_tree->Branch("calohit_time_v", "std::vector<float>", &_calohit_time_v);
1340  _calo_tree->Branch("calohit_time_y", "std::vector<float>", &_calohit_time_y);
1341  _calo_tree->Branch("calohit_nhit_u", "std::vector<unsigned>", &_calohit_nhit_u);
1342  _calo_tree->Branch("calohit_nhit_v", "std::vector<unsigned>", &_calohit_nhit_v);
1343  _calo_tree->Branch("calohit_nhit_y", "std::vector<unsigned>", &_calohit_nhit_y);
1344 
1345  _calo_tree->Branch("sumhit_charge_u", "std::vector<float>", &_sumhit_charge_u);
1346  _calo_tree->Branch("sumhit_charge_v", "std::vector<float>", &_sumhit_charge_v);
1347  _calo_tree->Branch("sumhit_charge_y", "std::vector<float>", &_sumhit_charge_y);
1348  _calo_tree->Branch("sumhit_wire_u", "std::vector<unsigned>", &_sumhit_wire_u);
1349  _calo_tree->Branch("sumhit_wire_v", "std::vector<unsigned>", &_sumhit_wire_v);
1350  _calo_tree->Branch("sumhit_wire_y", "std::vector<unsigned>", &_sumhit_wire_y);
1351  _calo_tree->Branch("sumhit_channel_u", "std::vector<unsigned>", &_sumhit_channel_u);
1352  _calo_tree->Branch("sumhit_channel_v", "std::vector<unsigned>", &_sumhit_channel_v);
1353  _calo_tree->Branch("sumhit_channel_y", "std::vector<unsigned>", &_sumhit_channel_y);
1354  _calo_tree->Branch("sumhit_multiplicity_u", "std::vector<int>", &_sumhit_multiplicity_u);
1355  _calo_tree->Branch("sumhit_multiplicity_v", "std::vector<int>", &_sumhit_multiplicity_v);
1356  _calo_tree->Branch("sumhit_multiplicity_y", "std::vector<int>", &_sumhit_multiplicity_y);
1357  _calo_tree->Branch("sumhit_width_u", "std::vector<float>", &_sumhit_width_u);
1358  _calo_tree->Branch("sumhit_width_v", "std::vector<float>", &_sumhit_width_v);
1359  _calo_tree->Branch("sumhit_width_y", "std::vector<float>", &_sumhit_width_y);
1360  _calo_tree->Branch("sumhit_time_u", "std::vector<float>", &_sumhit_time_u);
1361  _calo_tree->Branch("sumhit_time_v", "std::vector<float>", &_sumhit_time_v);
1362  _calo_tree->Branch("sumhit_time_y", "std::vector<float>", &_sumhit_time_y);
1363  _calo_tree->Branch("sumhit_nhit_u", "std::vector<unsigned>", &_sumhit_nhit_u);
1364  _calo_tree->Branch("sumhit_nhit_v", "std::vector<unsigned>", &_sumhit_nhit_v);
1365  _calo_tree->Branch("sumhit_nhit_y", "std::vector<unsigned>", &_sumhit_nhit_y);
1366 
1367  _calo_tree->Branch("backtracked_end_x", &_backtracked_end_x, "backtracked_end_x/F");
1368  _calo_tree->Branch("backtracked_end_y", &_backtracked_end_y, "backtracked_end_y/F");
1369  _calo_tree->Branch("backtracked_end_z", &_backtracked_end_z, "backtracked_end_z/F");
1370 
1371  _calo_tree->Branch("backtracked_start_x", &_backtracked_start_x, "backtracked_start_x/F");
1372  _calo_tree->Branch("backtracked_start_y", &_backtracked_start_y, "backtracked_start_y/F");
1373  _calo_tree->Branch("backtracked_start_z", &_backtracked_start_z, "backtracked_start_z/F");
1374  _calo_tree->Branch("backtracked_start_t", &_backtracked_start_t, "backtracked_start_t/F");
1375  // _calo_tree->Branch("backtracked_start_U", &_backtracked_start_U, "backtracked_start_U/F");
1376  // _calo_tree->Branch("backtracked_start_V", &_backtracked_start_V, "backtracked_start_V/F");
1377  // _calo_tree->Branch("backtracked_start_Y", &_backtracked_start_Y, "backtracked_start_Y/F");
1378  _calo_tree->Branch("backtracked_sce_start_x", &_backtracked_sce_start_x, "backtracked_sce_start_x/F");
1379  _calo_tree->Branch("backtracked_sce_start_y", &_backtracked_sce_start_y, "backtracked_sce_start_y/F");
1380  _calo_tree->Branch("backtracked_sce_start_z", &_backtracked_sce_start_z, "backtracked_sce_start_z/F");
1381  // _calo_tree->Branch("backtracked_sce_start_U", &_backtracked_sce_start_U, "backtracked_sce_start_U/F");
1382  // _calo_tree->Branch("backtracked_sce_start_V", &_backtracked_sce_start_V, "backtracked_sce_start_V/F");
1383  // _calo_tree->Branch("backtracked_sce_start_Y", &_backtracked_sce_start_Y, "backtracked_sce_start_Y/F");
1384 
1385  _calo_tree->Branch("backtracked_process_is_stopping", &_backtracked_process_is_stopping, "backtracked_process_is_stopping/O");
1386  _calo_tree->Branch("backtracked_end_in_tpc", &_backtracked_end_in_tpc, "backtracked_end_in_tpc/O");
1387 
1388  _calo_tree->Branch("generation", &_generation, "generation/i");
1389  _calo_tree->Branch("trk_daughters", &_trk_daughters, "trk_daughters/i");
1390  _calo_tree->Branch("daughters", &_daughters, "daughters/i");
1391  _calo_tree->Branch("shr_daughters", &_shr_daughters, "shr_daughters/i");
1392  _calo_tree->Branch("n_pfp", &_n_pfp, "n_pfp/i");
1393 
1394  // track information
1395  _calo_tree->Branch("trk_score", &_trk_score, "trk_score/F");
1396 
1397  _calo_tree->Branch("trk_theta", &_trk_theta, "trk_theta/F");
1398  _calo_tree->Branch("trk_phi", &_trk_phi, "trk_phi/F");
1399  _calo_tree->Branch("trk_len", &_trk_len, "trk_len/F");
1400 
1401  _calo_tree->Branch("trk_calo_range_u", &_trk_calo_range_u, "trk_calo_range_u/F");
1402  _calo_tree->Branch("trk_calo_range_v", &_trk_calo_range_v, "trk_calo_range_v/F");
1403  _calo_tree->Branch("trk_calo_range_y", &_trk_calo_range_y, "trk_calo_range_y/F");
1404 
1405  _calo_tree->Branch("trk_dir_x", &_trk_dir_x, "trk_dir_x/F");
1406  _calo_tree->Branch("trk_dir_y", &_trk_dir_y, "trk_dir_y/F");
1407  _calo_tree->Branch("trk_dir_z", &_trk_dir_z, "trk_dir_z/F");
1408 
1409  _calo_tree->Branch("longest", &_longest, "longest/I");
1410 
1411  _calo_tree->Branch("trk_start_x", &_trk_start_x, "trk_start_x/F");
1412  _calo_tree->Branch("trk_start_y", &_trk_start_y, "trk_start_y/F");
1413  _calo_tree->Branch("trk_start_z", &_trk_start_z, "trk_start_z/F");
1414 
1415  _calo_tree->Branch("trk_sce_start_x", &_trk_sce_start_x, "trk_sce_start_x/F");
1416  _calo_tree->Branch("trk_sce_start_y", &_trk_sce_start_y, "trk_sce_start_y/F");
1417  _calo_tree->Branch("trk_sce_start_z", &_trk_sce_start_z, "trk_sce_start_z/F");
1418 
1419  _calo_tree->Branch("trk_end_x", &_trk_end_x, "trk_end_x/F");
1420  _calo_tree->Branch("trk_end_y", &_trk_end_y, "trk_end_y/F");
1421  _calo_tree->Branch("trk_end_z", &_trk_end_z, "trk_end_z/F");
1422 
1423  _calo_tree->Branch("trk_sce_end_x", &_trk_sce_end_x, "trk_sce_end_x/F");
1424  _calo_tree->Branch("trk_sce_end_y", &_trk_sce_end_y, "trk_sce_end_y/F");
1425  _calo_tree->Branch("trk_sce_end_z", &_trk_sce_end_z, "trk_sce_end_z/F");
1426 
1427  _calo_tree->Branch("trk_bragg_p_u", &_trk_bragg_p_u, "trk_bragg_p_u/F");
1428  _calo_tree->Branch("trk_bragg_mu_u", &_trk_bragg_mu_u, "trk_bragg_mu_u/F");
1429  _calo_tree->Branch("trk_bragg_mip_u", &_trk_bragg_mip_u, "trk_bragg_mip_u/F");
1430  _calo_tree->Branch("trk_pid_chipr_u", &_trk_pid_chipr_u, "trk_pid_chipr_u/F");
1431  _calo_tree->Branch("trk_pid_chika_u", &_trk_pid_chika_u, "trk_pid_chika_u/F");
1432  _calo_tree->Branch("trk_pid_chipi_u", &_trk_pid_chipi_u, "trk_pid_chipi_u/F");
1433  _calo_tree->Branch("trk_pid_chimu_u", &_trk_pid_chimu_u, "trk_pid_chimu_u/F");
1434  _calo_tree->Branch("trk_pida_u", &_trk_pida_u, "trk_pida_u/F");
1435 
1436  _calo_tree->Branch("trk_bragg_p_v", &_trk_bragg_p_v, "trk_bragg_p_v/F");
1437  _calo_tree->Branch("trk_bragg_mu_v", &_trk_bragg_mu_v, "trk_bragg_mu_v/F");
1438  _calo_tree->Branch("trk_bragg_mip_v", &_trk_bragg_mip_v, "trk_bragg_mip_v/F");
1439  _calo_tree->Branch("trk_pid_chipr_v", &_trk_pid_chipr_v, "trk_pid_chipr_v/F");
1440  _calo_tree->Branch("trk_pid_chika_v", &_trk_pid_chika_v, "trk_pid_chika_v/F");
1441  _calo_tree->Branch("trk_pid_chipi_v", &_trk_pid_chipi_v, "trk_pid_chipi_v/F");
1442  _calo_tree->Branch("trk_pid_chimu_v", &_trk_pid_chimu_v, "trk_pid_chimu_v/F");
1443  _calo_tree->Branch("trk_pida_v", &_trk_pida_v, "trk_pida_v/F");
1444 
1445  _calo_tree->Branch("trk_bragg_p_y", &_trk_bragg_p_y, "trk_bragg_p_y/F");
1446  _calo_tree->Branch("trk_bragg_mu_y", &_trk_bragg_mu_y, "trk_bragg_mu_y/F");
1447  _calo_tree->Branch("trk_bragg_mip_y", &_trk_bragg_mip_y, "trk_bragg_mip_y/F");
1448  _calo_tree->Branch("trk_pid_chipr_y", &_trk_pid_chipr_y, "trk_pid_chipr_y/F");
1449  _calo_tree->Branch("trk_pid_chika_y", &_trk_pid_chika_y, "trk_pid_chika_y/F");
1450  _calo_tree->Branch("trk_pid_chipi_y", &_trk_pid_chipi_y, "trk_pid_chipi_y/F");
1451  _calo_tree->Branch("trk_pid_chimu_y", &_trk_pid_chimu_y, "trk_pid_chimu_y/F");
1452  _calo_tree->Branch("trk_pida_y", &_trk_pida_y, "trk_pida_y/F");
1453 
1454  _calo_tree->Branch("trk_bragg_p_three_planes", &_trk_bragg_p_three_planes, "trk_bragg_p_three_planes/F");
1455 
1456  _calo_tree->Branch("trk_mcs_muon_mom", &_trk_mcs_muon_mom, "trk_mcs_muon_mom/F");
1457  _calo_tree->Branch("trk_energy_proton", &_trk_energy_proton, "trk_energy_proton/F");
1458  _calo_tree->Branch("trk_energy_muon", &_trk_energy_muon, "trk_energy_muon/F");
1459 
1460  // dedx vector
1461  _calo_tree->Branch("dqdx_u", "std::vector<float>", &_dqdx_u);
1462  _calo_tree->Branch("dqdx_v", "std::vector<float>", &_dqdx_v);
1463  _calo_tree->Branch("dqdx_y", "std::vector<float>", &_dqdx_y);
1464 
1465  _calo_tree->Branch("dedx_u", "std::vector<float>", &_dedx_u);
1466  _calo_tree->Branch("dedx_v", "std::vector<float>", &_dedx_v);
1467  _calo_tree->Branch("dedx_y", "std::vector<float>", &_dedx_y);
1468 
1469  _calo_tree->Branch("dedx_channel_u", "std::vector<unsigned>", &_dedx_channel_u);
1470  _calo_tree->Branch("dedx_channel_v", "std::vector<unsigned>", &_dedx_channel_v);
1471  _calo_tree->Branch("dedx_channel_y", "std::vector<unsigned>", &_dedx_channel_y);
1472 
1473  _calo_tree->Branch("rr_u", "std::vector<float>", &_rr_u);
1474  _calo_tree->Branch("rr_v", "std::vector<float>", &_rr_v);
1475  _calo_tree->Branch("rr_y", "std::vector<float>", &_rr_y);
1476 
1477  _calo_tree->Branch("pitch_u", "std::vector<float>", &_pitch_u);
1478  _calo_tree->Branch("pitch_v", "std::vector<float>", &_pitch_v);
1479  _calo_tree->Branch("pitch_y", "std::vector<float>", &_pitch_y);
1480 
1481  _calo_tree->Branch("sx", "std::vector<float>", & _sx);
1482  _calo_tree->Branch("sy", "std::vector<float>", & _sy);
1483  _calo_tree->Branch("sz", "std::vector<float>", & _sz);
1484 
1485  _calo_tree->Branch("w_u", "std::vector<float>", &_w_u);
1486  _calo_tree->Branch("w_v", "std::vector<float>", &_w_v);
1487  _calo_tree->Branch("w_y", "std::vector<float>", &_w_y);
1488 
1489  _calo_tree->Branch("t_u", "std::vector<float>", &_t_u);
1490  _calo_tree->Branch("t_v", "std::vector<float>", &_t_v);
1491  _calo_tree->Branch("t_y", "std::vector<float>", &_t_y);
1492 
1493  _calo_tree->Branch("x_u", "std::vector<float>", &_x_u);
1494  _calo_tree->Branch("x_v", "std::vector<float>", &_x_v);
1495  _calo_tree->Branch("x_y", "std::vector<float>", &_x_y);
1496 
1497  _calo_tree->Branch("y_u", "std::vector<float>", &_y_u);
1498  _calo_tree->Branch("y_v", "std::vector<float>", &_y_v);
1499  _calo_tree->Branch("y_y", "std::vector<float>", &_y_y);
1500 
1501  _calo_tree->Branch("z_u", "std::vector<float>", &_z_u);
1502  _calo_tree->Branch("z_v", "std::vector<float>", &_z_v);
1503  _calo_tree->Branch("z_y", "std::vector<float>", &_z_y);
1504 
1505  _calo_tree->Branch("dir_x_u", "std::vector<float>", &_dir_x_u);
1506  _calo_tree->Branch("dir_x_v", "std::vector<float>", &_dir_x_v);
1507  _calo_tree->Branch("dir_x_y", "std::vector<float>", &_dir_x_y);
1508 
1509  _calo_tree->Branch("dir_y_u", "std::vector<float>", &_dir_y_u);
1510  _calo_tree->Branch("dir_y_v", "std::vector<float>", &_dir_y_v);
1511  _calo_tree->Branch("dir_y_y", "std::vector<float>", &_dir_y_y);
1512 
1513  _calo_tree->Branch("dir_z_u", "std::vector<float>", &_dir_z_u);
1514  _calo_tree->Branch("dir_z_v", "std::vector<float>", &_dir_z_v);
1515  _calo_tree->Branch("dir_z_y", "std::vector<float>", &_dir_z_y);
1516 }
1517 
1519 {
1520 }
1521 
1522 std::vector<unsigned> FinddEdxHits(const anab::Calorimetry &calo, const std::vector<art::Ptr<recob::Hit>> &hits) {
1523  std::vector<unsigned> ret;
1524 
1525  // NOTE: TpIndices are __actually__ the art::Ptr keys of the Hit's
1526  // Don't ask me why
1527  for (size_t ind: calo.TpIndices()) {
1528  bool found = false;
1529  for (const art::Ptr<recob::Hit> &hit: hits) {
1530  if (hit.key() == ind) {
1531  ret.push_back(hit->Channel());
1532  found = true;
1533  break;
1534  }
1535  }
1536  if (!found) {
1537  throw cet::exception("dEdx w/out Hit!");
1538  }
1539  }
1540  return ret;
1541 }
1542 
1543 float calcPitch(const geo::GeometryCore *geo, const geo::PlaneID &plane, TVector3 location, TVector3 direction, const spacecharge::SpaceCharge *SCEService=NULL) {
1544  float angletovert = geo->WireAngleToVertical(geo->View(plane), plane) - 0.5*::util::pi<>();
1545 
1546  // apply space charge change to dir
1547  if (SCEService) {
1548  geo::Point_t location_p(location);
1549  geo::Vector_t offset_v = SCEService->GetPosOffsets(location_p);
1550  TVector3 offset = TVector3(offset_v.X(), offset_v.Y(), offset_v.Z());
1551  // fix the x-sign
1552  if (location.X() < 0.) offset.SetX(-offset.X());
1553 
1554  // location a ~wire's distance along the track
1555  TVector3 location_dx = location + geo->WirePitch(plane) * direction;
1556 
1557  // Apply space charge to the offset location
1558  geo::Point_t location_dx_p(location_dx);
1559  geo::Vector_t offset_dx_v = SCEService->GetPosOffsets(location_dx_p);
1560  TVector3 offset_dx(offset_dx_v.X(), offset_dx_v.Y(), offset_dx_v.Z());
1561  // fix the x-sign
1562  if (location_dx.X() < 0.) offset_dx.SetX(-offset_dx.X());
1563 
1564  // this is the actual direction
1565  direction = (offset_dx + location_dx - offset - location).Unit();
1566  }
1567 
1568  // get the pitch
1569  float cosgamma = abs(cos(angletovert) * direction.Z() + sin(angletovert) * direction.Y());
1570  float pitch = geo->WirePitch(plane) / cosgamma;
1571 
1572  // map pitch back onto particle trajectory
1573  if (SCEService) {
1574  geo::Point_t location_p(location);
1575  geo::Vector_t offset_v = SCEService->GetPosOffsets(location_p);
1576  TVector3 offset(offset_v.X(), offset_v.Y(), offset_v.Z());
1577  // fix the x-sign
1578  if (location.X() < 0.) offset.SetX(-offset.X());
1579 
1580  TVector3 location_sce = location + offset;
1581 
1582  TVector3 location_sce_dx = location_sce + direction * pitch;
1583 
1584  // map this back onto the particle trajectory
1585  geo::Point_t location_sce_dx_p(location_sce_dx);
1586  geo::Vector_t back_v = SCEService->GetCalPosOffsets(location_sce_dx_p, plane.TPC);
1587  TVector3 back(back_v.X(), back_v.Y(), back_v.Z());
1588  TVector3 location_dx = location_sce_dx + back;
1589 
1590  pitch = (location - location_dx).Mag();
1591  }
1592 
1593  return pitch;
1594 }
1595 
1596 
1598  const std::vector<art::Ptr<recob::Wire>> &allWires,
1599  const std::vector<art::Ptr<recob::Hit>> &allHits,
1600  const art::Ptr<recob::PFParticle> &pfp,
1601  const art::Ptr<recob::Track> &trk,
1602  const std::vector<art::Ptr<recob::SpacePoint>> &spacepoints,
1603  const std::vector<art::Ptr<anab::Calorimetry>> &calos,
1604  const std::vector<art::Ptr<anab::ParticleID>> &pids,
1605  const std::vector<art::Ptr<recob::Hit>> &areaHits,
1606  const std::vector<art::Ptr<recob::Hit>> &trkHits,
1607  const std::vector<art::Ptr<recob::Hit>> &caloHits,
1608  const recob::MCSFitResult &muon_mcs,
1609  const sbn::RangeP &muon_range,
1610  const sbn::RangeP &proton_range,
1611  const bool fData,
1612  const std::vector<std::pair<int, float>> &particleMatches,
1613  const art::Ptr<simb::MCParticle> &trueParticle,
1614  const std::array<std::map<unsigned, std::vector<const sim::IDE*>>, 3> particle_ide_map,
1615  const std::array<std::vector<const sim::IDE*>,3> &allIDEs,
1616  const std::vector<geo::BoxBoundedGeo> &activeVolumes)
1617  //const std::vector<searchingfornues::BtPart> btparts_v,
1618  //const std::unique_ptr<art::FindManyP<simb::MCParticle, anab::BackTrackerHitMatchingData>> &assocMCPart)
1619 {
1620 
1621  art::ServiceHandle<cheat::BackTrackerService> bt_serv;
1622  const geo::GeometryCore *geometry = lar::providerFrom<geo::Geometry>();
1623  const spacecharge::SpaceCharge *spacecharge = lar::providerFrom<spacecharge::SpaceChargeService>();
1624  auto const clock_data = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(e);
1625  auto const dprop = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(e, clock_data);
1626 
1627  // TODO: variables to set
1628  _generation = -1;
1629  _shr_daughters = 0;
1630  _trk_daughters = 0;
1631  _trk_score = -1;
1632  _longest = -1;
1633 
1634  _daughters = pfp->NumDaughters();
1635  _pfpno = pfp->Self();
1636  _trkid = trk->ID();
1637 
1638  for (unsigned sp_i = 0; sp_i < spacepoints.size(); sp_i++) {
1639  _sx.push_back(spacepoints[sp_i]->XYZ()[0]);
1640  _sy.push_back(spacepoints[sp_i]->XYZ()[1]);
1641  _sz.push_back(spacepoints[sp_i]->XYZ()[2]);
1642  }
1643 
1644  for (const auto &wire: allWires) {
1645  unsigned plane_id = geometry->ChannelToWire(wire->Channel()).at(0).Plane;
1646 
1647  if (plane_id == 0) {
1648  _integrated_charge_u.push_back(0);
1649  for (auto const &range: wire->SignalROI().get_ranges()) {
1650  for (float val: range) _integrated_charge_u.back() += val;
1651  }
1652  }
1653  else if (plane_id == 1) {
1654  _integrated_charge_v.push_back(0);
1655  for (auto const &range: wire->SignalROI().get_ranges()) {
1656  for (float val: range) _integrated_charge_v.back() += val;
1657  }
1658  }
1659  else if (plane_id == 2) {
1660  _integrated_charge_y.push_back(0);
1661  for (auto const &range: wire->SignalROI().get_ranges()) {
1662  for (float val: range) _integrated_charge_y.back() += val;
1663  }
1664  }
1665  }
1666 
1667  FillHits(clock_data, allHits,
1689  );
1690 
1691  FillHits(clock_data, areaHits,
1713  );
1714 
1715  FillHits(clock_data, trkHits,
1737  );
1738 
1739  FillHits(clock_data, caloHits,
1761  );
1762 
1763  FillHits(clock_data, caloHits,
1785  false);
1786 
1787  // store Backtracking
1788  if (!fData)
1789  {
1790  _backtracked_e = trueParticle->E();
1791  _backtracked_pdg = trueParticle->PdgCode();
1792  float trueTrackE = 0.;
1793  float matchE = -1;
1794  for (auto pair: particleMatches) {
1795  trueTrackE += pair.second;
1796  if (pair.first == trueParticle->TrackId()) matchE = pair.second;
1797  }
1798  assert(matchE > 0.);
1799  _backtracked_purity = matchE / trueTrackE;
1800 
1801  float trueParticleE = 0.;
1802  _backtracked_q_u = 0.;
1803  _backtracked_q_v = 0.;
1804  _backtracked_q_y = 0.;
1805  _backtracked_qtotal_u = 0.;
1806  _backtracked_qtotal_v = 0.;
1807  _backtracked_qtotal_y = 0.;
1811 
1812  for (auto const &ide_pair: particle_ide_map[0]) {
1813  _backtracked_c_u.push_back(ide_pair.first);
1814  _backtracked_pc_q_u.push_back(0);
1815  _backtracked_pc_e_u.push_back(0);
1816  for (const sim::IDE *ide: ide_pair.second) {
1817  trueParticleE += ide->energy;
1820  _backtracked_pc_q_u.back() += ide->numElectrons;
1821  _backtracked_pc_e_u.back() += ide->energy;
1822  }
1823  }
1824 
1825  for (auto const &ide_pair: particle_ide_map[1]) {
1826  _backtracked_c_v.push_back(ide_pair.first);
1827  _backtracked_pc_q_v.push_back(0);
1828  _backtracked_pc_e_v.push_back(0);
1829  for (const sim::IDE *ide: ide_pair.second) {
1830  trueParticleE += ide->energy;
1833  _backtracked_pc_q_v.back() += ide->numElectrons;
1834  _backtracked_pc_e_v.back() += ide->energy;
1835  }
1836  }
1837 
1838  for (auto const &ide_pair: particle_ide_map[2]) {
1839  _backtracked_c_y.push_back(ide_pair.first);
1840  _backtracked_pc_q_y.push_back(0);
1841  _backtracked_pc_e_y.push_back(0);
1842  for (const sim::IDE *ide: ide_pair.second) {
1843  trueParticleE += ide->energy;
1846  _backtracked_pc_q_y.back() += ide->numElectrons;
1847  _backtracked_pc_e_y.back() += ide->energy;
1848  }
1849  }
1850 
1851  for (auto ide: allIDEs[0]) {
1852  _backtracked_qtotal_u += ide->numElectrons;
1853  }
1854  for (auto ide: allIDEs[1]) {
1855  _backtracked_qtotal_v += ide->numElectrons;
1856  }
1857  for (auto ide: allIDEs[2]) {
1858  _backtracked_qtotal_y += ide->numElectrons;
1859  }
1860 
1861  _backtracked_completeness = matchE / trueParticleE;
1862 
1863  // TODO: set overlay purity
1864 
1865  _backtracked_theta = trueParticle->Momentum().Theta();
1866  _backtracked_phi = trueParticle->Momentum().Phi();
1867 
1868  _backtracked_px = trueParticle->Momentum().Px();
1869  _backtracked_py = trueParticle->Momentum().Py();
1870  _backtracked_pz = trueParticle->Momentum().Pz();
1871 
1872  _backtracked_end_x = trueParticle->EndPosition().X();
1873  _backtracked_end_y = trueParticle->EndPosition().Y();
1874  _backtracked_end_z = trueParticle->EndPosition().Z();
1875 
1876  _backtracked_start_x = trueParticle->Position().X();
1877  _backtracked_start_y = trueParticle->Position().Y();
1878  _backtracked_start_z = trueParticle->Position().Z();
1879  _backtracked_start_t = trueParticle->Position().T();
1880 
1884 
1885  // save the trajectory
1886  for (unsigned i_traj = 0; i_traj < trueParticle->NumberTrajectoryPoints(); i_traj++) {
1887  _backtracked_x.push_back(trueParticle->Vx(i_traj));
1888  _backtracked_y.push_back(trueParticle->Vy(i_traj));
1889  _backtracked_z.push_back(trueParticle->Vz(i_traj));
1890 
1891  _backtracked_dirx.push_back(trueParticle->Px(i_traj) / trueParticle->P(i_traj));
1892  _backtracked_diry.push_back(trueParticle->Py(i_traj) / trueParticle->P(i_traj));
1893  _backtracked_dirz.push_back(trueParticle->Pz(i_traj) / trueParticle->P(i_traj));
1894  }
1895 
1896  // also map between wires and the trajectory
1897  //
1898  // First setup all the traj containers
1906  _backtracked_de_c_u.insert(_backtracked_de_c_u.end(), _backtracked_c_u.size(), 0.);
1909 
1917  _backtracked_de_c_v.insert(_backtracked_de_c_v.end(), _backtracked_c_v.size(), 0.);
1920 
1928  _backtracked_de_c_y.insert(_backtracked_de_c_y.end(), _backtracked_c_y.size(), 0.);
1931 
1932  for (geo::TPCID tpc: geometry->IterateTPCIDs()) {
1933  for (geo::PlaneID planeID: geometry->IteratePlaneIDs(tpc)) {
1934  auto const &plane = planeID.Plane;
1935  if (plane > 2) continue; // protect against bad plane ID
1936 
1937  int lastWire = -1000000;
1938  int last_traj = 0;
1939  for (unsigned i_traj = 0; i_traj < trueParticle->NumberTrajectoryPoints()-1; i_traj++) {
1940  TVector3 thispoint = trueParticle->Position(i_traj).Vect();
1941  TVector3 nextpoint = trueParticle->Position(i_traj+1).Vect();
1942 
1943  geo::Point_t thispoint_p(thispoint.X(), thispoint.Y(), thispoint.Z());
1944  geo::Point_t nextpoint_p(nextpoint.X(), nextpoint.Y(), nextpoint.Z());
1945 
1946  double thiswirecoord = geometry->WireCoordinate(thispoint_p, planeID);
1947  double nextwirecoord = geometry->WireCoordinate(nextpoint_p, planeID);
1948  int wireStart = std::nearbyint((thiswirecoord >= nextwirecoord) ? std::floor(thiswirecoord) : std::ceil(thiswirecoord));
1949  int wireEnd = std::nearbyint((thiswirecoord >= nextwirecoord) ? std::floor(nextwirecoord) : std::ceil(nextwirecoord));
1950  // if we're not crossing a wire continue
1951  if (wireStart == wireEnd) continue;
1952 
1953  // check the validity of the range of wires
1954  if (!(wireStart >= 0 && wireStart < (int)geometry->Plane(planeID).Nwires())) continue;
1955  if (!(wireEnd >= 0 && wireEnd <= (int)geometry->Plane(planeID).Nwires())) continue;
1956 
1957  // if this wire is the same as the last skip it
1958  if (wireStart == lastWire) {
1959  if (wireStart < wireEnd) wireStart ++;
1960  else wireStart --;
1961  }
1962  // again continue if this wouldn't cross a new wire
1963  if (wireStart == wireEnd) continue;
1964 
1965  // load the trajectory information at this point
1966  double locX = trueParticle->Position(i_traj).X();
1967  double locY = trueParticle->Position(i_traj).Y();
1968  double locZ = trueParticle->Position(i_traj).Z();
1969  double dirX = trueParticle->Momentum(i_traj).Vect().Unit().X();
1970  double dirY = trueParticle->Momentum(i_traj).Vect().Unit().Y();
1971  double dirZ = trueParticle->Momentum(i_traj).Vect().Unit().Z();
1972  double deltaE = (trueParticle->Momentum(last_traj).E() - trueParticle->Momentum(i_traj+1).E()) / abs(wireEnd - wireStart); // average dE over wires
1973 
1974  double pitch = calcPitch(geometry, planeID, trueParticle->Position(i_traj).Vect(), trueParticle->Momentum(i_traj).Vect().Unit());
1975  double pitchSCE = calcPitch(geometry, planeID, trueParticle->Position(i_traj).Vect(), trueParticle->Momentum(i_traj).Vect().Unit(), spacecharge);
1976 
1977  // save
1978  int incl = wireStart < wireEnd ? 1: -1;
1979  for (int wire = wireStart; wire != wireEnd; wire += incl) {
1980  lastWire = wire;
1981  unsigned channel = geometry->PlaneWireToChannel(planeID.Plane, wire, planeID.TPC, planeID.Cryostat);
1982 
1983  if (plane == 0) {
1984  int index = -1;
1985  for (unsigned i_test = 0; i_test < _backtracked_c_u.size(); i_test++) {
1986  if (_backtracked_c_u[i_test] == channel) {
1987  index = i_test;
1988  break;
1989  }
1990  }
1991  if (index < 0) continue;
1992 
1993  _backtracked_nloc_c_u[index] ++;
1994  _backtracked_locx_c_u[index] = locX;
1995  _backtracked_locy_c_u[index] = locY;
1996  _backtracked_locz_c_u[index] = locZ;
1997  _backtracked_dirx_c_u[index] = dirX;
1998  _backtracked_diry_c_u[index] = dirY;
1999  _backtracked_dirz_c_u[index] = dirZ;
2000  _backtracked_de_c_u[index] = deltaE;
2001  _backtracked_pitch_c_u[index] = pitch;
2002  _backtracked_scepitch_c_u[index] = pitchSCE;
2003  }
2004  else if (plane == 1) {
2005  int index = -1;
2006  for (unsigned i_test = 0; i_test < _backtracked_c_v.size(); i_test++) {
2007  if (_backtracked_c_v[i_test] == channel) {
2008  index = i_test;
2009  break;
2010  }
2011  }
2012  if (index < 0) continue;
2013 
2014  _backtracked_nloc_c_v[index] ++;
2015  _backtracked_locx_c_v[index] = locX;
2016  _backtracked_locy_c_v[index] = locY;
2017  _backtracked_locz_c_v[index] = locZ;
2018  _backtracked_dirx_c_v[index] = dirX;
2019  _backtracked_diry_c_v[index] = dirY;
2020  _backtracked_dirz_c_v[index] = dirZ;
2021  _backtracked_de_c_v[index] = deltaE;
2022  _backtracked_pitch_c_v[index] = pitch;
2023  _backtracked_scepitch_c_v[index] = pitchSCE;
2024  }
2025  else if (plane == 2) {
2026  int index = -1;
2027  for (unsigned i_test = 0; i_test < _backtracked_c_y.size(); i_test++) {
2028  if (_backtracked_c_y[i_test] == channel) {
2029  index = i_test;
2030  break;
2031  }
2032  }
2033  if (index < 0) continue;
2034 
2035  _backtracked_nloc_c_y[index] ++;
2036  _backtracked_locx_c_y[index] = locX;
2037  _backtracked_locy_c_y[index] = locY;
2038  _backtracked_locz_c_y[index] = locZ;
2039  _backtracked_dirx_c_y[index] = dirX;
2040  _backtracked_diry_c_y[index] = dirY;
2041  _backtracked_dirz_c_y[index] = dirZ;
2042  _backtracked_de_c_y[index] = deltaE;
2043  _backtracked_pitch_c_y[index] = pitch;
2044  _backtracked_scepitch_c_y[index] = pitchSCE;
2045  }
2046 
2047 
2048  }
2049  last_traj = i_traj;
2050  }
2051  }
2052  }
2053 
2054  // TODO: implement spacecharge
2056  // TODO: do something special for electrons and photons???
2057  // if (mcp.pdg == 11 || mcp.pdg == 22)
2058  // {
2059  // reco_st[0] += searchingfornues::x_offset(mcp.start_t);
2060  // }
2062  _backtracked_sce_start_x = reco_st[0];
2063  _backtracked_sce_start_y = reco_st[1];
2064  _backtracked_sce_start_z = reco_st[2];
2065 
2066  _backtracked_sce_start_U = XYZtoPlanecoordinate(reco_st[0], reco_st[1], reco_st[2], 0);
2067  _backtracked_sce_start_V = XYZtoPlanecoordinate(reco_st[0], reco_st[1], reco_st[2], 1);
2068  _backtracked_sce_start_Y = XYZtoPlanecoordinate(reco_st[0], reco_st[1], reco_st[2], 2);
2069  _backtracked_process_is_stopping = (trueParticle->EndProcess() == "Decay" ||
2070  trueParticle->EndProcess() == "CoupledTransportation" ||
2071  trueParticle->EndProcess() == "FastScintillation" ||
2072  trueParticle->EndProcess() == "muMinusCaptureAtRest" ||
2073  trueParticle->EndProcess() == "LArVoxelReadoutScoringProcess");
2074 
2075  std::cout << "PID: " << _backtracked_pdg << " Process: " << trueParticle->EndProcess() << " is stopping: " << _backtracked_process_is_stopping << std::endl;
2076 
2077  std::vector<geoalgo::AABox> aa_volumes;
2078  _backtracked_end_in_tpc = false;
2079  for (const geo::BoxBoundedGeo &AV: activeVolumes) {
2080  if (AV.ContainsPosition(trueParticle->Position().Vect()) && AV.ContainsPosition(trueParticle->EndPosition().Vect())) {
2081  _backtracked_end_in_tpc = true;
2082  aa_volumes.emplace_back(AV.MinX(), AV.MinY(), AV.MinZ(), AV.MaxX(), AV.MaxY(), AV.MaxZ());
2083  break;
2084  }
2085  }
2086 
2087  _backtracked_length_start_to_end = (trueParticle->Position().Vect() - trueParticle->EndPosition().Vect()).Mag();
2088  _backtracked_length = 0.;
2089  for (unsigned i = 1; i < trueParticle->NumberTrajectoryPoints(); i++) {
2090  _backtracked_length += ContainedLength(trueParticle->Position(i-1).Vect(), trueParticle->Position(i).Vect(), aa_volumes);
2091  }
2092  }
2093 
2094  // Kinetic energy using tabulated stopping power (GeV)
2095  float mcs_momentum_muon = muon_range.range_p;
2096  float momentum_proton = proton_range.range_p;
2097  float energy_proton = std::sqrt(std::pow(momentum_proton, 2) + std::pow(proton->Mass(), 2)) - proton->Mass();
2098  float energy_muon = std::sqrt(std::pow(mcs_momentum_muon, 2) + std::pow(muon->Mass(), 2)) - muon->Mass();
2099 
2100  _trk_mcs_muon_mom = mcs_momentum_muon;
2101  _trk_energy_proton = energy_proton;
2102  _trk_energy_muon = energy_muon;
2103 
2104  _trk_theta = trk->Theta();
2105  _trk_phi = trk->Phi();
2106  // TODO: SCE
2107  _trk_len = trk->Length();
2108 
2109  _trk_dir_x = trk->StartDirection().X();
2110  _trk_dir_y = trk->StartDirection().Y();
2111  _trk_dir_z = trk->StartDirection().Z();
2112 
2113  _trk_start_x = trk->Start().X();
2114  _trk_start_y = trk->Start().Y();
2115  _trk_start_z = trk->Start().Z();
2116 
2117  _trk_end_x = trk->End().X();
2118  _trk_end_y = trk->End().Y();
2119  _trk_end_z = trk->End().Z();
2120 
2121  // TODO: SCE
2122  float _trk_start_sce[3];
2123  (void) _trk_start_sce;
2127 
2128  float _trk_end_sce[3];
2129  (void) _trk_end_sce;
2133 
2134  // fill other particle ID
2135  for (const art::Ptr<anab::ParticleID> pid: pids) {
2136 
2137  // Assign dummy values.
2138 
2139  double chi2_muon = 0.;
2140  double chi2_pion = 0.;
2141  double chi2_kaon = 0.;
2142  double chi2_proton = 0.;
2143  double pida = 0.;
2144  auto plane = pid->PlaneID().Plane;
2145 
2146  // Loop over algorithm scores and extract the ones we want.
2147  // Extract the plane from any matching algorithm.
2148 
2149  std::vector<anab::sParticleIDAlgScores> AlgScoresVec = pid->ParticleIDAlgScores();
2150  for (size_t i_algscore=0; i_algscore<AlgScoresVec.size(); i_algscore++){
2151  anab::sParticleIDAlgScores AlgScore = AlgScoresVec.at(i_algscore);
2152  if (AlgScore.fAlgName == "Chi2"){
2153  if (TMath::Abs(AlgScore.fAssumedPdg) == 13) { // chi2mu
2154  chi2_muon = AlgScore.fValue;
2155  if (AlgScore.fPlaneMask.count() == 1) {
2156  if (AlgScore.fPlaneMask.test(0)) plane = 0;
2157  if (AlgScore.fPlaneMask.test(1)) plane = 1;
2158  if (AlgScore.fPlaneMask.test(2)) plane = 2;
2159  }
2160  }
2161  else if (TMath::Abs(AlgScore.fAssumedPdg) == 211) { // chi2pi
2162  chi2_pion = AlgScore.fValue;
2163  if (AlgScore.fPlaneMask.count() == 1) {
2164  if (AlgScore.fPlaneMask.test(0)) plane = 0;
2165  if (AlgScore.fPlaneMask.test(1)) plane = 1;
2166  if (AlgScore.fPlaneMask.test(2)) plane = 2;
2167  }
2168  }
2169  else if (TMath::Abs(AlgScore.fAssumedPdg) == 321) { // chi2ka
2170  chi2_kaon = AlgScore.fValue;
2171  if (AlgScore.fPlaneMask.count() == 1) {
2172  if (AlgScore.fPlaneMask.test(0)) plane = 0;
2173  if (AlgScore.fPlaneMask.test(1)) plane = 1;
2174  if (AlgScore.fPlaneMask.test(2)) plane = 2;
2175  }
2176  }
2177  else if (TMath::Abs(AlgScore.fAssumedPdg) == 2212) { // chi2pr
2178  chi2_proton = AlgScore.fValue;
2179  if (AlgScore.fPlaneMask.count() == 1) {
2180  if (AlgScore.fPlaneMask.test(0)) plane = 0;
2181  if (AlgScore.fPlaneMask.test(1)) plane = 1;
2182  if (AlgScore.fPlaneMask.test(2)) plane = 2;
2183  }
2184  }
2185  }
2186  else if (AlgScore.fVariableType==anab::kPIDA){
2187  pida = AlgScore.fValue;
2188  if (AlgScore.fPlaneMask.count() == 1) {
2189  if (AlgScore.fPlaneMask.test(0)) plane = 0;
2190  if (AlgScore.fPlaneMask.test(1)) plane = 1;
2191  if (AlgScore.fPlaneMask.test(2)) plane = 2;
2192  }
2193  }
2194  }
2195  if (plane > 2) continue;
2196 
2197  if (plane == 0) {
2198  // TODO: bragg variable??
2199  _trk_bragg_p_u = -1;
2200  _trk_bragg_mu_u = -1;
2201  _trk_bragg_mip_u = -1;
2202 
2203  _trk_pid_chipr_u = chi2_proton;
2204  _trk_pid_chika_u = chi2_kaon;
2205  _trk_pid_chipi_u = chi2_pion;
2206  _trk_pid_chimu_u = chi2_muon;
2207  _trk_pida_u = pida;
2208  }
2209  else if (plane == 1) {
2210  // TODO: bragg variable??
2211  _trk_bragg_p_v = -1;
2212  _trk_bragg_mu_v = -1;
2213  _trk_bragg_mip_v = -1;
2214 
2215  _trk_pid_chipr_v = chi2_proton;
2216  _trk_pid_chika_v = chi2_kaon;
2217  _trk_pid_chipi_v = chi2_pion;
2218  _trk_pid_chimu_v = chi2_muon;
2219  _trk_pida_v = pida;
2220  }
2221  else if (plane == 2) {
2222  // TODO: bragg variable??
2223  _trk_bragg_p_y = -1;
2224  _trk_bragg_mu_y = -1;
2225  _trk_bragg_mip_y = -1;
2226 
2227  _trk_pid_chipr_y = chi2_proton;
2228  _trk_pid_chika_y = chi2_kaon;
2229  _trk_pid_chipi_y = chi2_pion;
2230  _trk_pid_chimu_y = chi2_muon;
2231  _trk_pida_y = pida;
2232  }
2233  }
2234 
2235  // fill Calorimetry
2236  for (const art::Ptr<anab::Calorimetry> calo : calos)
2237  {
2238  // TODO: will this work for ICARUS?
2239  auto const& plane = calo->PlaneID().Plane;
2240  if (plane>2)
2241  {
2242  continue;
2243  }
2244  auto const& xyz_v = calo->XYZ();
2245 
2246  if (plane == 0)
2247  {
2248  _trk_calo_range_u = calo->Range();
2249  _dqdx_u = calo->dQdx();
2250  _rr_u = calo->ResidualRange();
2251  _pitch_u = calo->TrkPitchVec();
2252  for (auto xyz : xyz_v)
2253  {
2254  _w_u.push_back(geometry->WireCoordinate(xyz, calo->PlaneID()));
2255  _t_u.push_back(dprop.ConvertXToTicks(xyz.X(), calo->PlaneID()));
2256  _x_u.push_back(xyz.X());
2257  _y_u.push_back(xyz.Y());
2258  _z_u.push_back(xyz.Z());
2259 
2260  float _dir_u[3];
2261  TrkDirectionAtXYZ(*trk, xyz.X(), xyz.Y(), xyz.Z(), _dir_u);
2262  _dir_x_u.push_back(_dir_u[0]);
2263  _dir_y_u.push_back(_dir_u[1]);
2264  _dir_z_u.push_back(_dir_u[2]);
2265  }
2266  // TODO: ShrFit???
2267  _dedx_u = calo->dEdx();
2268  _dedx_channel_u = FinddEdxHits(*calo, trkHits);
2269 
2270  }
2271  else if (plane == 1)
2272  {
2273  _trk_calo_range_v = calo->Range();
2274 
2275  _dqdx_v = calo->dQdx();
2276  _rr_v = calo->ResidualRange();
2277  _pitch_v = calo->TrkPitchVec();
2278  for (auto xyz : xyz_v)
2279  {
2280  _w_v.push_back(geometry->WireCoordinate(xyz, calo->PlaneID()));
2281  _t_v.push_back(dprop.ConvertXToTicks(xyz.X(), calo->PlaneID()));
2282  _x_v.push_back(xyz.X());
2283  _y_v.push_back(xyz.Y());
2284  _z_v.push_back(xyz.Z());
2285 
2286  float _dir_v[3];
2287  TrkDirectionAtXYZ(*trk, xyz.X(), xyz.Y(), xyz.Z(), _dir_v);
2288  _dir_x_v.push_back(_dir_v[0]);
2289  _dir_y_v.push_back(_dir_v[1]);
2290  _dir_z_v.push_back(_dir_v[2]);
2291  }
2292  // TODO: ShrFit???
2293  _dedx_v = calo->dEdx();
2294  _dedx_channel_v = FinddEdxHits(*calo, trkHits);
2295  }
2296  else if (plane == 2) //collection
2297  {
2298  _trk_calo_range_y = calo->Range();
2299 
2300  _dqdx_y = calo->dQdx();
2301  _rr_y = calo->ResidualRange();
2302  _pitch_y = calo->TrkPitchVec();
2303  for (auto xyz : xyz_v)
2304  {
2305  _w_y.push_back(geometry->WireCoordinate(xyz, calo->PlaneID()));
2306  _t_y.push_back(dprop.ConvertXToTicks(xyz.X(), calo->PlaneID()));
2307  _x_y.push_back(xyz.X());
2308  _y_y.push_back(xyz.Y());
2309  _z_y.push_back(xyz.Z());
2310 
2311  float _dir_y[3];
2312  TrkDirectionAtXYZ(*trk, xyz.X(), xyz.Y(), xyz.Z(), _dir_y);
2313  _dir_x_y.push_back(_dir_y[0]);
2314  _dir_y_y.push_back(_dir_y[1]);
2315  _dir_z_y.push_back(_dir_y[2]);
2316  }
2317  // TODO: ShrFit???
2318  _dedx_y = calo->dEdx();
2319  _dedx_channel_y = FinddEdxHits(*calo, trkHits);
2320  }
2321  }
2322 
2323  _calo_tree->Fill();
2324 }
2325 
2326 // Define helper functions
2327  void TrkDirectionAtXYZ(const recob::Track trk, const double x, const double y, const double z, float out[3])
2328  {
2329  float min_dist = 1000;
2330  size_t i_min = -1;
2331  for(size_t i=0; i < trk.NumberTrajectoryPoints(); i++)
2332  {
2333  if (trk.HasValidPoint(i))
2334  { // check this point is valid
2335  auto point_i = trk.LocationAtPoint(i);
2336  float distance = distance3d((double)point_i.X(), (double)point_i.Y(), (double)point_i.Z(),
2337  x, y, z);
2338  if (distance < min_dist)
2339  {
2340  min_dist = distance;
2341  i_min = i;
2342  }
2343  }// if point is valid
2344  }// for all track points
2345 
2346  if (i_min == (size_t)-1) return;
2347 
2348  auto direction = trk.DirectionAtPoint(i_min);
2349  out[0] = (float)direction.X();
2350  out[1] = (float)direction.Y();
2351  out[2] = (float)direction.Z();
2352 
2353  float norm;
2354  norm = out[0]*out[0] + out[1]*out[1] + out[2]*out[2];
2355  if (fabs(norm -1) > 0.001)
2356  {
2357  std::cout << "i_min = " << i_min << std::endl;
2358  std::cout << "minimum distance = " << min_dist << std::endl;
2359  std::cout << "out[0], out[1], out[2] = " << out[0] << " , " << out[1] << " , " << out[2] << std::endl;
2360  std::cout << "norm = " << norm << std::endl;
2361  }
2362  }
2363 
2365  const std::vector<art::Ptr<recob::Hit>> &hits,
2366  std::vector<float> &charge_u,
2367  std::vector<float> &charge_v,
2368  std::vector<float> &charge_y,
2369  std::vector<unsigned> &wire_u,
2370  std::vector<unsigned> &wire_v,
2371  std::vector<unsigned> &wire_y,
2372  std::vector<unsigned> &channel_u,
2373  std::vector<unsigned> &channel_v,
2374  std::vector<unsigned> &channel_y,
2375  std::vector<int> &multiplicity_u,
2376  std::vector<int> &multiplicity_v,
2377  std::vector<int> &multiplicity_y,
2378  std::vector<float> &width_u,
2379  std::vector<float> &width_v,
2380  std::vector<float> &width_y,
2381  std::vector<float> &time_u,
2382  std::vector<float> &time_v,
2383  std::vector<float> &time_y,
2384  std::vector<unsigned> &nhit_u,
2385  std::vector<unsigned> &nhit_v,
2386  std::vector<unsigned> &nhit_y,
2387  bool use_integral) {
2388 
2389  struct HitInfo {
2390  float charge;
2391  int multiplicity;
2392  float width;
2393  int start;
2394  int end;
2395  float time;
2396  int nhit;
2397  int wire;
2398  HitInfo(): charge(0), multiplicity(0), width(0), start(0), end(0), time(0.), nhit(0) {}
2399  };
2400 
2401  std::map<unsigned, HitInfo> hit_map_u;
2402  std::map<unsigned, HitInfo> hit_map_v;
2403  std::map<unsigned, HitInfo> hit_map_y;
2404 
2405  for (const art::Ptr<recob::Hit> hit: hits) {
2406  if (hit->WireID().Plane == 0) {
2407  // if using summed ADC method to count charge, don't double-count hits in the same snippet
2408  if (!use_integral && hit_map_u[hit->Channel()].start == hit->StartTick() && hit_map_u[hit->Channel()].end == hit->EndTick()) {
2409  continue;
2410  }
2411  hit_map_u[hit->Channel()].charge += (use_integral) ? hit->Integral() : hit->SummedADC();
2412  hit_map_u[hit->Channel()].multiplicity = std::max(hit_map_u[hit->Channel()].multiplicity, (int) hit->Multiplicity());
2413  hit_map_u[hit->Channel()].start = hit_map_u[hit->Channel()].nhit ? std::min(hit_map_u[hit->Channel()].start, hit->StartTick()) : hit->StartTick();
2414  hit_map_u[hit->Channel()].end = hit_map_u[hit->Channel()].nhit ? std::max(hit_map_u[hit->Channel()].end, hit->EndTick()) : hit->EndTick();
2415  hit_map_u[hit->Channel()].width = (hit_map_u[hit->Channel()].end - hit_map_u[hit->Channel()].start);
2416  hit_map_u[hit->Channel()].time = (hit->PeakTime() + hit_map_u[hit->Channel()].time * hit_map_u[hit->Channel()].nhit) / (hit_map_u[hit->Channel()].nhit + 1);
2417  hit_map_u[hit->Channel()].nhit ++;
2418  hit_map_u[hit->Channel()].wire = hit->WireID().Wire;
2419  }
2420  else if (hit->WireID().Plane == 1) {
2421  // if using summed ADC method to count charge, don't double-count hits in the same snippet
2422  if (!use_integral && hit_map_v[hit->Channel()].start == hit->StartTick() && hit_map_v[hit->Channel()].end == hit->EndTick()) {
2423  continue;
2424  }
2425  hit_map_v[hit->Channel()].charge += (use_integral) ? hit->Integral() : hit->SummedADC();
2426  hit_map_v[hit->Channel()].multiplicity = std::max(hit_map_v[hit->Channel()].multiplicity, (int) hit->Multiplicity());
2427  hit_map_v[hit->Channel()].start = hit_map_v[hit->Channel()].nhit ? std::min(hit_map_v[hit->Channel()].start, hit->StartTick()) : hit->StartTick();
2428  hit_map_v[hit->Channel()].end = hit_map_v[hit->Channel()].nhit ? std::max(hit_map_v[hit->Channel()].end, hit->EndTick()) : hit->EndTick();
2429  hit_map_v[hit->Channel()].width = (hit_map_v[hit->Channel()].end - hit_map_v[hit->Channel()].start);
2430  hit_map_v[hit->Channel()].time = (hit->PeakTime() + hit_map_v[hit->Channel()].time * hit_map_v[hit->Channel()].nhit) / (hit_map_v[hit->Channel()].nhit + 1);
2431  hit_map_v[hit->Channel()].nhit ++;
2432  hit_map_v[hit->Channel()].wire = hit->WireID().Wire;
2433  }
2434  else {
2435  // if using summed ADC method to count charge, don't double-count hits in the same snippet
2436  if (!use_integral && hit_map_y[hit->Channel()].start == hit->StartTick() && hit_map_y[hit->Channel()].end == hit->EndTick()) {
2437  continue;
2438  }
2439  hit_map_y[hit->Channel()].charge += (use_integral) ? hit->Integral() : hit->SummedADC();
2440  hit_map_y[hit->Channel()].multiplicity = std::max(hit_map_y[hit->Channel()].multiplicity, (int) hit->Multiplicity());
2441  hit_map_y[hit->Channel()].start = hit_map_y[hit->Channel()].nhit ? std::min(hit_map_y[hit->Channel()].start, hit->StartTick()) : hit->StartTick();
2442  hit_map_y[hit->Channel()].end = hit_map_y[hit->Channel()].nhit ? std::max(hit_map_y[hit->Channel()].end, hit->EndTick()) : hit->EndTick();
2443  hit_map_y[hit->Channel()].width = (hit_map_y[hit->Channel()].end - hit_map_y[hit->Channel()].start);
2444  hit_map_y[hit->Channel()].time = (hit->PeakTime() + hit_map_y[hit->Channel()].time * hit_map_y[hit->Channel()].nhit) / (hit_map_y[hit->Channel()].nhit + 1);
2445  hit_map_y[hit->Channel()].nhit ++;
2446  hit_map_y[hit->Channel()].wire = hit->WireID().Wire;
2447  }
2448  }
2449 
2450  for (auto const &pair: hit_map_u) {
2451  channel_u.push_back(pair.first);
2452  charge_u.push_back(pair.second.charge);
2453  multiplicity_u.push_back(pair.second.multiplicity);
2454  width_u.push_back(pair.second.width);
2455  time_u.push_back(pair.second.time);
2456  nhit_u.push_back(pair.second.nhit);
2457  wire_u.push_back(pair.second.wire);
2458  }
2459  for (auto const &pair: hit_map_v) {
2460  channel_v.push_back(pair.first);
2461  charge_v.push_back(pair.second.charge);
2462  multiplicity_v.push_back(pair.second.multiplicity);
2463  width_v.push_back(pair.second.width);
2464  time_v.push_back(pair.second.time);
2465  nhit_v.push_back(pair.second.nhit);
2466  wire_v.push_back(pair.second.wire);
2467  }
2468  for (auto const &pair: hit_map_y) {
2469  channel_y.push_back(pair.first);
2470  charge_y.push_back(pair.second.charge);
2471  multiplicity_y.push_back(pair.second.multiplicity);
2472  width_y.push_back(pair.second.width);
2473  time_y.push_back(pair.second.time);
2474  nhit_y.push_back(pair.second.nhit);
2475  wire_y.push_back(pair.second.wire);
2476  }
2477 
2478 }
2479 
2480 // TODO: include space charge
2481 void True2RecoMappingXYZ(float t,float x, float y, float z, float out[3]) {
2482  (void) t;
2483  out[0] = x;
2484  out[1] = y;
2485  out[2] = z;
2486 }
2487 
2488  float XYZtoPlanecoordinate(const float x, const float y, const float z, const int plane)
2489  {
2490  auto const* geom = ::lar::providerFrom<geo::Geometry>();
2491  geo::Point_t p(x,y,z);
2492  geo::TPCID tpc = geom->FindTPCAtPosition(p);
2493  if (!tpc) return -1e6;
2494  geo::PlaneID planeID(tpc, plane);
2495  double _wire2cm = geom->WirePitch(planeID);
2496 
2497  return geom->WireCoordinate(p, planeID) * _wire2cm;
2498  }
2499 
2500  float distance3d(const float& x1, const float& y1, const float& z1,
2501  const float& x2, const float& y2, const float& z2)
2502  {
2503  return sqrt((x1-x2)*(x1-x2) +
2504  (y1-y2)*(y1-y2) +
2505  (z1-z2)*(z1-z2));
2506 
2507  }
2508 
2509 float ContainedLength(const TVector3 &v0, const TVector3 &v1,
2510  const std::vector<geoalgo::AABox> &boxes) {
2511  static const geoalgo::GeoAlgo algo;
2512 
2513  // if points are the same, return 0
2514  if ((v0 - v1).Mag() < 1e-6) return 0;
2515 
2516  // construct individual points
2517  geoalgo::Point_t p0(v0);
2518  geoalgo::Point_t p1(v1);
2519 
2520  // construct line segment
2521  geoalgo::LineSegment line(p0, p1);
2522 
2523  double length = 0;
2524 
2525  // total contained length is sum of lengths in all boxes
2526  // assuming they are non-overlapping
2527  for (auto const &box: boxes) {
2528  int n_contained = box.Contain(p0) + box.Contain(p1);
2529  // both points contained -- length is total length (also can break out of loop)
2530  if (n_contained == 2) {
2531  length = (v1 - v0).Mag();
2532  break;
2533  }
2534  // one contained -- have to find intersection point (which must exist)
2535  if (n_contained == 1) {
2536  auto intersections = algo.Intersection(line, box);
2537  // Because of floating point errors, it can sometimes happen
2538  // that there is 1 contained point but no "Intersections"
2539  // if one of the points is right on the edge
2540  if (intersections.size() == 0) {
2541  // determine which point is on the edge
2542  double tol = 1e-5;
2543  bool p0_edge = algo.SqDist(p0, box) < tol;
2544  bool p1_edge = algo.SqDist(p1, box) < tol;
2545  assert(p0_edge || p1_edge);
2546  // contained one is on edge -- can treat both as not contained
2547  //
2548  // In this case, no length
2549  if ((p0_edge && box.Contain(p0)) || (box.Contain(p1) && p1_edge))
2550  continue;
2551  // un-contaned one is on edge -- treat both as contained
2552  else if ((p0_edge && box.Contain(p1)) || (box.Contain(p0) && p1_edge)) {
2553  length = (v1 - v0).Mag();
2554  break;
2555  }
2556  else {
2557  assert(false); // bad
2558  }
2559  }
2560  // floating point errors can also falsely cause 2 intersection points
2561  //
2562  // in this case, one of the intersections must be very close to the
2563  // "contained" point, so the total contained length will be about
2564  // the same as the distance between the two intersection points
2565  else if (intersections.size() == 2) {
2566  length += (intersections.at(0).ToTLorentzVector().Vect() - intersections.at(1).ToTLorentzVector().Vect()).Mag();
2567  continue;
2568  }
2569  // "Correct"/ideal case -- 1 intersection point
2570  else if (intersections.size() == 1) {
2571  // get TVector at intersection point
2572  TVector3 int_tv(intersections.at(0).ToTLorentzVector().Vect());
2573  length += ( box.Contain(p0) ? (v0 - int_tv).Mag() : (v1 - int_tv).Mag() );
2574  }
2575  else assert(false); // bad
2576  }
2577  // none contained -- either must have zero or two intersections
2578  if (n_contained == 0) {
2579  auto intersections = algo.Intersection(line, box);
2580  if (!(intersections.size() == 0 || intersections.size() == 2)) {
2581  // more floating point error fixes...
2582  //
2583  // figure out which points are near the edge
2584  double tol = 1e-5;
2585  bool p0_edge = algo.SqDist(p0, box) < tol;
2586  bool p1_edge = algo.SqDist(p1, box) < tol;
2587  // and which points are near the intersection
2588  TVector3 vint = intersections.at(0).ToTLorentzVector().Vect();
2589 
2590  bool p0_int = (v0 - vint).Mag() < tol;
2591  bool p1_int = (v1 - vint).Mag() < tol;
2592  // exactly one of them should produce the intersection
2593  assert((p0_int && p0_edge) != (p1_int && p1_edge));
2594  // void variables when assert-ions are turned off
2595  (void) p0_int; (void) p1_int;
2596 
2597  // both close to edge -- full length is contained
2598  if (p0_edge && p1_edge) {
2599  length += (v0 - v1).Mag();
2600  }
2601  // otherwise -- one of them is not on an edge, no length is contained
2602  else {}
2603  }
2604  // assert(intersections.size() == 0 || intersections.size() == 2);
2605  else if (intersections.size() == 2) {
2606  TVector3 start(intersections.at(0).ToTLorentzVector().Vect());
2607  TVector3 end(intersections.at(1).ToTLorentzVector().Vect());
2608  length += (start - end).Mag();
2609  }
2610  }
2611  }
2612 
2613  return length;
2614 }//ContainedLength
2615 
2616 } // namespace analysis
2617 
2618 DEFINE_ART_MODULE(analysis::CalorimetryAnalysis)
2619 #endif
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
TrackID_t trackID
Geant4 supplied track ID.
Definition: SimChannel.h:116
void resetTTree(TTree *_tree)
reset ttree branches
process_name opflash particleana ie ie ie z
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
Algorithm to compute various geometrical relation among geometrical objects. In particular functions ...
BEGIN_PROLOG TPC Trig offset(g4 rise time) ProjectToHeight
Definition: CORSIKAGen.fcl:7
std::vector< std::vector< geo::BoxBoundedGeo > > fTPCVolumes
Utilities related to art service access.
PlaneGeo const & Plane(unsigned int const p, unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified wire.
ClusterModuleLabel join with tracks
const geo::GeometryCore * geometry
process_name opflash particleana ie x
static constexpr size_t kPFParticlePrimary
Define index to signify primary particle.
Definition: PFParticle.h:61
void FillCalorimetry(art::Event const &e, const std::vector< art::Ptr< recob::Wire >> &allWires, const std::vector< art::Ptr< recob::Hit >> &allHits, const art::Ptr< recob::PFParticle > &pfp, const art::Ptr< recob::Track > &trk, const std::vector< art::Ptr< recob::SpacePoint >> &spacepoints, const std::vector< art::Ptr< anab::Calorimetry >> &calos, const std::vector< art::Ptr< anab::ParticleID >> &pid, const std::vector< art::Ptr< recob::Hit >> &areaHits, const std::vector< art::Ptr< recob::Hit >> &trkHits, const std::vector< art::Ptr< recob::Hit >> &caloHits, const recob::MCSFitResult &muon_mcs, const sbn::RangeP &muon_range, const sbn::RangeP &proton_range, const bool fData, const std::vector< std::pair< int, float >> &particleMatches, const art::Ptr< simb::MCParticle > &trueParticle, const std::array< std::map< unsigned, std::vector< const sim::IDE * >>, 3 > particle_ide_map, const std::array< std::vector< const sim::IDE * >, 3 > &allIDEs, const std::vector< geo::BoxBoundedGeo > &activeVolumes)
auto const tol
Definition: SurfXYZTest.cc:16
double SqDist(const Line_t &line, const Point_t &pt) const
Declaration of signal hit object.
Point_t const & LocationAtPoint(size_t i) const
pdgs p
Definition: selectors.fcl:22
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
Representation of a simple 3D line segment Defines a finite 3D straight line by having the start and ...
Geometry information for a single TPC.
Definition: TPCGeo.h:38
void TrkDirectionAtXYZ(const recob::Track trk, const double x, const double y, const double z, float out[3])
bool HasValidPoint(size_t i) const
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
geo::BoxBoundedGeo const & ActiveBoundingBox() const
Returns the box of the active volume of this TPC.
Definition: TPCGeo.h:320
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
std::size_t size(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:561
process_name use argoneut_mc_hitfinder track
process_name hit
Definition: cheaterreco.fcl:51
float fValue
Result of Particle ID algorithm/test.
Definition: ParticleID.h:28
void fillDefault()
Fill Default info for event associated to neutrino.
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
BEGIN_PROLOG TPC
IteratorBox< TPC_id_iterator,&GeometryCore::begin_TPC_id,&GeometryCore::end_TPC_id > IterateTPCIDs() const
Enables ranged-for loops on all TPC IDs of the detector.
float calcPitch(const geo::GeometryCore *geo, const geo::PlaneID &plane, TVector3 location, TVector3 direction, const spacecharge::SpaceCharge *SCEService=NULL)
std::bitset< 8 > fPlaneMask
Bitset for PlaneID used by algorithm, allowing for multiple planes and up to 8 total planes...
Definition: ParticleID.h:29
float distance3d(const float &x1, const float &y1, const float &z1, const float &x2, const float &y2, const float &z2)
process_name gaushit a
IteratorBox< plane_id_iterator,&GeometryCore::begin_plane_id,&GeometryCore::end_plane_id > IteratePlaneIDs() const
Enables ranged-for loops on all plane IDs of the detector.
std::string fAlgName
&lt; determined particle ID
Definition: ParticleID.h:23
process_name can override from command line with o or output calo
Definition: pid.fcl:40
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
T abs(T value)
kVariableType fVariableType
Variable type enum: defined in ParticleID_VariableTypeEnums.h. Set to kNotSet by default.
Definition: ParticleID.h:24
void True2RecoMappingXYZ(float t, float x, float y, float z, float out[3])
double Length(size_t p=0) const
Access to various track properties.
then echo ***************************************echo array
Definition: find_fhicl.sh:28
process_name opflash particleana ie ie y
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
void FillHits(const detinfo::DetectorClocksData &clockData, const std::vector< art::Ptr< recob::Hit >> &hits, std::vector< float > &charge_u, std::vector< float > &charge_v, std::vector< float > &charge_y, std::vector< unsigned > &wire_u, std::vector< unsigned > &wire_v, std::vector< unsigned > &wire_y, std::vector< unsigned > &channel_u, std::vector< unsigned > &channel_v, std::vector< unsigned > &channel_y, std::vector< int > &multiplicity_u, std::vector< int > &multiplicity_v, std::vector< int > &multiplicity_y, std::vector< float > &width_u, std::vector< float > &width_v, std::vector< float > &width_y, std::vector< float > &time_u, std::vector< float > &time_v, std::vector< float > &time_y, std::vector< unsigned > &nhit_u, std::vector< unsigned > &nhit_v, std::vector< unsigned > &nhit_y, bool use_integral=true)
Ionization at a point of the TPC sensitive volume.
Definition: SimChannel.h:86
size_t Parent() const
Definition: PFParticle.h:96
float energy
energy deposited by ionization by this track ID and time [MeV]
Definition: SimChannel.h:118
std::vector< unsigned > FinddEdxHits(const anab::Calorimetry &calo, const std::vector< art::Ptr< recob::Hit >> &hits)
CalorimetryAnalysis(const fhicl::ParameterSet &pset)
Constructor.
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
bool IsPrimary() const
Returns whether the particle is the root of the flow.
Definition: PFParticle.h:86
std::vector< geo::BoxBoundedGeo > fActiveVolumes
The data type to uniquely identify a TPC.
Definition: geo_types.h:386
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.
Provides recob::Track data product.
auto norm(Vector const &v)
Return norm of the specified vector.
Class storing the result of the Maximum Likelihood fit of Multiple Coulomb Scattering angles between ...
Definition: MCSFitResult.h:19
float range_p
Definition: RangeP.h:7
raw::ChannelID_t PlaneWireToChannel(WireID const &wireid) const
Returns the ID of the TPC channel connected to the specified wire.
const std::vector< size_t > & TpIndices() const
Definition: Calorimetry.h:115
Hierarchical representation of particle flow.
Definition: PFParticle.h:44
A base class aware of world box coordinatesAn object describing a simple shape can inherit from this ...
Definition: BoxBoundedGeo.h:33
Contains all timing reference information for the detector.
float XYZtoPlanecoordinate(const float x, const float y, const float z, const int plane)
unsigned int Nwires() const
Number of wires in this plane.
Definition: PlaneGeo.h:269
do i e
Declaration of basic channel signal object.
Vector_t DirectionAtPoint(size_t i) const
void setBranches(TTree *_tree)
set branches for TTree
art::ServiceHandle< art::TFileService > tfs
void analyze(art::Event const &e) override
Analysis function.
std::vector< art::InputTag > fHitProducers
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:406
std::vector< Point_t > Intersection(const AABox_t &box, const HalfLine_t &line, bool back=false) const
Intersection between a HalfLine and an AABox.
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
void respondToOpenInputFile(const art::FileBlock &fb) override
float ContainedLength(const TVector3 &v0, const TVector3 &v1, const std::vector< geoalgo::AABox > &boxes)
double WireAngleToVertical(geo::View_t view, geo::TPCID const &tpcid) const
Returns the angle of the wires in the specified view from vertical.
physics associatedGroupsWithLeft p1
BEGIN_PROLOG could also be cout
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a &quot;fitted&quot; track:
float numElectrons
number of electrons at the readout for this track ID and time
Definition: SimChannel.h:117
int fAssumedPdg
PDG of particle hypothesis assumed by algorithm, if applicable. Set to 0 by default.
Definition: ParticleID.h:27