AnaRootParser_module.cc
Go to the documentation of this file.
1 // Framework includes
11 #include "art_root_io/TFileService.h"
12 #include "art_root_io/TFileDirectory.h"
13 #include "canvas/Persistency/Common/FindMany.h"
15 #include "fhiclcpp/ParameterSet.h"
17 
30 #include "lardataobj/RawData/raw.h"
54 #include "larreco/RecoAlg/TrajectoryMCSFitter.h" //uBoone fitter
59 
61 
63 
64 #include <cstddef> // std::ptrdiff_t
65 #include <cstring> // std::memcpy()
66 #include <vector>
67 #include <map>
68 #include <iterator> // std::begin(), std::end()
69 #include <string>
70 #include <sstream>
71 #include <fstream>
72 #include <algorithm>
73 #include <functional> // std::mem_fun_ref
74 #include <typeinfo>
75 #include <memory> // std::unique_ptr<>
76 
77 #include "TTree.h"
78 #include "TTimeStamp.h"
79 
80 constexpr int kNplanes = 2; //number of wire planes
81 constexpr int kMaxHits = 40000; //maximum number of hits;
82 constexpr int kMaxTrackHits = 2000; //maximum number of hits on a track
83 constexpr int kMaxTrackers = 15; //number of trackers passed into fTrackModuleLabel
84 constexpr int kMaxVertices = 500; //max number of 3D vertices
85 constexpr int kMaxVertexAlgos = 10; //max number of vertex algorithms
86 constexpr unsigned short kMaxAuxDets = 4; ///< max number of auxiliary detector cells per MC particle
87 constexpr int kMaxFlashes = 1000; //maximum number of flashes
88 constexpr int kMaxExternCounts = 1000; //maximum number of External Counters
89 constexpr int kMaxShowerHits = 10000; //maximum number of hits on a shower
90 constexpr int kMaxTruth = 10; //maximum number of neutrino truth interactions
91 constexpr int kMaxClusters = 1000; //maximum number of clusters;
92 constexpr int kMaxReadoutTicksInAllChannels = 76800000; //protoDUNE: 10 000 ticks * (8*960) channel
93 constexpr int kMaxChannels = 7680; //protoDUNE: (8*960) channel
94 
95 constexpr int kMaxNDaughtersPerPFP = 10; //maximum number of daughters per PFParticle
96 constexpr int kMaxNClustersPerPFP = 10; //maximum number of clusters per PFParticle
97 constexpr int kMaxNPFPNeutrinos = 5; //maximum number of reconstructed neutrino PFParticles
98 
99 /// total_extent<T>::value has the total number of elements of an array
100 template <typename T>
101 struct total_extent {
102  using value_type = size_t;
103  static constexpr value_type value
104  = sizeof(T) / sizeof(typename std::remove_all_extents<T>::type);
105 }; // total_extent<>
106 
107 
108 namespace dune {
109 
110  /// Data structure with all the tree information.
111  ///
112  /// Can connect to a tree, clear its fields and resize its data.
114  public:
115 
116  /// A wrapper to a C array (needed to embed an array into a vector)
117  template <typename Array_t>
118  class BoxedArray {
119  protected:
120  Array_t array; // actual data
121 
122  public:
125 
126  BoxedArray() {} // no initialization
127  BoxedArray(const This_t& from)
128  { std::memcpy((char*) &(data()), (char*) &(from.data()), sizeof(Array_t)); }
129 
130  Array_t& data() { return array; }
131  const Array_t& data() const { return array; }
132 
133  //@{
134  /// begin/end interface
135  static constexpr size_t size() { return total_extent<Array_t>::value; }
136  Data_t* begin() { return reinterpret_cast<Data_t*>(&array); }
137  const Data_t* begin() const { return reinterpret_cast<const Data_t*>(&array); }
138  Data_t* end() { return begin() + size(); }
139  const Data_t* end() const { return begin() + size(); }
140  //@}
141 
142  //@{
143  /// Array interface
144  auto operator[] (size_t index) -> decltype(*array) { return array[index]; }
145  auto operator[] (size_t index) const -> decltype(*array) { return array[index]; }
146  auto operator+ (ptrdiff_t index) -> decltype(&*array) { return array + index; }
147  auto operator+ (ptrdiff_t index) const -> decltype(&*array) { return array + index; }
148  auto operator- (ptrdiff_t index) -> decltype(&*array) { return array - index; }
149  auto operator- (ptrdiff_t index) const -> decltype(&*array) { return array - index; }
150  auto operator* () -> decltype(*array) { return *array; }
151  auto operator* () const -> decltype(*array) { return *array; }
152 
153  operator decltype(&array[0]) () { return &array[0]; }
154  operator decltype(&array[0]) () const { return &array[0]; }
155  //@}
156 
157  }; // BoxedArray
158 
159  /// Tracker algorithm result
160  ///
161  /// Can connect to a tree, clear its fields and resize its data.
163  public:
164  /* Data structure size:
165  *
166  * TrackData_t<Short_t> : 2 bytes/track
167  * TrackData_t<Float_t> : 4 bytes/track
168  * TrackPlaneData_t<Float_t>, TrackPlaneData_t<Int_t>: 12 bytes/track
169  * TrackHitData_t<Float_t> : 24k bytes/track
170  * TrackHitCoordData_t<Float_t> : 72k bytes/track
171  */
172  template <typename T>
173  using TrackData_t = std::vector<T>;
174  template <typename T>
175  using TrackPlaneData_t = std::vector<BoxedArray<T[kNplanes]>>;
176  template <typename T>
177  using TrackHitData_t = std::vector<BoxedArray<T[kNplanes][kMaxTrackHits]>>;
178  template <typename T>
179  using TrackHitCoordData_t = std::vector<BoxedArray<T[kNplanes][kMaxTrackHits][3]>>;
180 
181  size_t MaxTracks; ///< maximum number of storable tracks
182 
183  Short_t ntracks; //number of reconstructed tracks
186  TrackPlaneData_t<Int_t> trkidtruth; //true geant trackid
187  TrackPlaneData_t<Short_t> trkorigin; //_ev_origin 0: unknown, 1: neutrino, 2: cosmic, 3: supernova, 4: singles
198 
199  Float_t trkdedx2[10000];
200  Float_t trkdqdx2[10000];
201  Float_t trktpc2[10000];
202  Float_t trkx2[10000];
203  Float_t trky2[10000];
204  Float_t trkz2[10000];
205 
206 
207  Float_t hittrkx[10000];
208  Float_t hittrky[10000];
209  Float_t hittrkz[10000];
210 
211  Float_t hittrklocaltrackdirectionx[10000];
212  Float_t hittrklocaltrackdirectiony[10000];
213  Float_t hittrklocaltrackdirectionz[10000];
214  Float_t hittrklocaltrackdirectiontheta[10000];
215  Float_t hittrklocaltrackdirectionphi[10000];
216 
217  Float_t hittrkpitchC[10000];
218 
219  Float_t hittrkds[10000];
220 
221  Short_t hittrkchannel[10000];
222  Short_t hittrktpc[10000];
223  Short_t hittrkview[10000];
224  Short_t hittrkwire[10000];
225  Float_t hittrkpeakT[10000];
226  Float_t hittrkchargeintegral[10000];
227  Float_t hittrkph[10000];
228  Float_t hittrkchargesum[10000];
229  Float_t hittrkstarT[10000];
230  Float_t hittrkendT[10000];
231  Float_t hittrkrms[10000];
232  Float_t hittrkgoddnessofFit[10000];
233  Short_t hittrkmultiplicity[10000];
234  Int_t hittrktrueID[10000];
235  Float_t hittrktrueEnergyMax[10000];
236  Float_t hittrktrueEnergyFraction[10000];
237 
238  // more track info
250  TrackData_t<Float_t> trkstartx; // starting x position.
251  TrackData_t<Float_t> trkstarty; // starting y position.
252  TrackData_t<Float_t> trkstartz; // starting z position.
253  TrackData_t<Float_t> trkstartd; // starting distance to boundary.
254  TrackData_t<Float_t> trkendx; // ending x position.
255  TrackData_t<Float_t> trkendy; // ending y position.
256  TrackData_t<Float_t> trkendz; // ending z position.
257  TrackData_t<Float_t> trkendd; // ending distance to boundary.
258  TrackData_t<Float_t> trkflashT0; // t0 per track from matching tracks to flashes (in ns)
259  TrackData_t<Float_t> trktrueT0; // t0 per track from truth information (in ns)
260  TrackData_t<Float_t> trkpurity; // track purity based on hit information
261  TrackData_t<Float_t> trkcompleteness; //track completeness based on hit information
262  TrackData_t<int> trkg4id; //true g4 track id for the reconstructed track
263  TrackData_t<int> trkorig; //origin of the track
277  TrackData_t<Float_t> trkchi2PerNDF; // length along trajectory.
278  TrackData_t<Float_t> trkNDF; // length along trajectory.
279  TrackData_t<Float_t> trklen; // length along trajectory.
280  TrackData_t<Float_t> trklenstraightline; // shortest distance betweem start and end point of track
281  TrackData_t<Float_t> trkmomrange; // track momentum from range using CSDA tables
282  TrackData_t<Float_t> trkmommschi2; // track momentum from multiple scattering Chi2 method
283  TrackData_t<Float_t> trkmommsllhd; // track momentum from multiple scattering LLHD method
284  TrackData_t<Float_t> trkmommscmic; //TODO comment here
285  TrackData_t<Float_t> trkmommscfwd; //TODO comment here
286  TrackData_t<Float_t> trkmommscbwd; //TODO comment here
289  TrackData_t<Short_t> trksvtxid; // Vertex ID associated with the track start
290  TrackData_t<Short_t> trkevtxid; // Vertex ID associated with the track end
291  TrackPlaneData_t<Int_t> trkpidpdg; // particle PID pdg code
293  TrackPlaneData_t<Float_t> trkpidchipr; // particle PID chisq for proton
294  TrackPlaneData_t<Float_t> trkpidchika; // particle PID chisq for kaon
295  TrackPlaneData_t<Float_t> trkpidchipi; // particle PID chisq for pion
296  TrackPlaneData_t<Float_t> trkpidchimu; // particle PID chisq for muon
298  TrackData_t<Float_t> trkpidmvamu; // particle MVA value for muon PID
299  TrackData_t<Float_t> trkpidmvae; // particle MVA value for electron PID
300  TrackData_t<Float_t> trkpidmvapich; // particle MVA value for charged pion PID
301  TrackData_t<Float_t> trkpidmvaphoton; // particle MVA value for photon PID
302  TrackData_t<Float_t> trkpidmvapr; // particle MVA value for proton PID
303  TrackData_t<Short_t> trkpidbestplane; // this is defined as the plane with most hits
304 
305  TrackData_t<Short_t> trkhasPFParticle; // whether this belongs to a PFParticle
306  TrackData_t<Short_t> trkPFParticleID; // if hasPFParticle, its ID
307 
308  /// Creates an empty tracker data structure
309  TrackDataStruct(): MaxTracks(0) { Clear(); }
310  /// Creates a tracker data structure allowing up to maxTracks tracks
311  TrackDataStruct(size_t maxTracks): MaxTracks(maxTracks) { Clear(); }
312  void Clear();
313  void SetMaxTracks(size_t maxTracks)
314  { MaxTracks = maxTracks; Resize(MaxTracks); }
315  void Resize(size_t nTracks);
316  void SetAddresses(TTree* pTree, std::string tracker, bool isCosmics);
317 
318  size_t GetMaxTracks() const { return MaxTracks; }
319  size_t GetMaxPlanesPerTrack(int /* iTrack */ = 0) const
320  { return (size_t) kNplanes; }
321  size_t GetMaxHitsPerTrack(int /* iTrack */ = 0, int /* ipl */ = 0) const
322  { return (size_t) kMaxTrackHits; }
323 
324  }; // class TrackDataStruct
325 
326  //Vertex data struct
328  public:
329  template <typename T>
330  using VertexData_t = std::vector<T>;
331 
332  size_t MaxVertices; ///< maximum number of storable vertices
333 
334  Short_t nvtx; //number of reconstructed tracks
335  VertexData_t<Short_t> vtxId; // the vertex ID.
336  VertexData_t<Float_t> vtxx; // x position.
337  VertexData_t<Float_t> vtxy; // y position.
338  VertexData_t<Float_t> vtxz; // z position.
339 
340  VertexData_t<Short_t> vtxhasPFParticle; // whether this belongs to a PFParticle
341  VertexData_t<Short_t> vtxPFParticleID; // if hasPFParticle, its ID
342 
343  VertexDataStruct(): MaxVertices(0) { Clear(); }
344  VertexDataStruct(size_t maxVertices): MaxVertices(maxVertices) { Clear(); }
345  void Clear();
346  void SetMaxVertices(size_t maxVertices)
347  { MaxVertices = maxVertices; Resize(MaxVertices); }
348  void Resize(size_t nVertices);
349  void SetAddresses(TTree* pTree, std::string tracker, bool isCosmics);
350 
351  size_t GetMaxVertices() const { return MaxVertices; }
352  }; // class VertexDataStruct
353 
354 
355  /// Shower algorithm result
356  ///
357  /// Can connect to a tree, clear its fields and resize its data.
359  public:
360  /* Data structure size:
361  *
362  * ShowerData_t<Short_t> : 2 bytes/shower
363  * ShowerData_t<Float_t> : 4 bytes/shower
364  * ShowerPlaneData_t<Float_t>, ShowerPlaneData_t<Int_t>: 12 bytes/shower
365  * ShowerHitData_t<Float_t> : 24k bytes/shower
366  * ShowerHitCoordData_t<Float_t> : 72k bytes/shower
367  */
368  template <typename T>
369  using ShowerData_t = std::vector<T>;
370  template <typename T>
371  using ShowerPlaneData_t = std::vector<BoxedArray<T[kNplanes]>>;
372  template <typename T>
373  using ShowerHitData_t = std::vector<BoxedArray<T[kNplanes][kMaxShowerHits]>>;
374  template <typename T>
375  using ShowerHitCoordData_t = std::vector<BoxedArray<T[kNplanes][kMaxShowerHits][3]>>;
376 
377  std::string name; ///< name of the shower algorithm (for branch names)
378 
379  size_t MaxShowers; ///< maximum number of storable showers
380 
381  /// @{
382  /// @name Branch data structures
383  Short_t nshowers; ///< number of showers
385  ShowerData_t<Short_t> shwr_bestplane; ///< Shower best plane
386  ShowerData_t<Float_t> shwr_length; ///< Shower length
387  ShowerData_t<Float_t> shwr_startdcosx; ///< X directional cosine at start of shower
388  ShowerData_t<Float_t> shwr_startdcosy; ///< Y directional cosine at start of shower
389  ShowerData_t<Float_t> shwr_startdcosz; ///< Z directional cosine at start of shower
390  ShowerData_t<Float_t> shwr_startx; ///< startx of shower
391  ShowerData_t<Float_t> shwr_starty; ///< starty of shower
392  ShowerData_t<Float_t> shwr_startz; ///< startz of shower
393  ShowerPlaneData_t<Float_t> shwr_totEng; ///< Total energy of the shower per plane
394  ShowerPlaneData_t<Float_t> shwr_dedx; ///< dE/dx of the shower per plane
395  ShowerPlaneData_t<Float_t> shwr_mipEng; ///< Total MIP energy of the shower per plane
396 
397  ShowerData_t<Float_t> shwr_pidmvamu; // particle MVA value for muon PID
398  ShowerData_t<Float_t> shwr_pidmvae; // particle MVA value for electron PID
399  ShowerData_t<Float_t> shwr_pidmvapich; // particle MVA value for charged pion PID
400  ShowerData_t<Float_t> shwr_pidmvaphoton; // particle MVA value for photon PID
401  ShowerData_t<Float_t> shwr_pidmvapr; // particle MVA value for proton PID
402 
403 
404  ShowerData_t<Short_t> shwr_hasPFParticle; // whether this belongs to a PFParticle
405  ShowerData_t<Short_t> shwr_PFParticleID; // if hasPFParticle, its ID
406  /// @}
407 
408  /// Creates a shower data structure allowing up to maxShowers showers
409  ShowerDataStruct(std::string new_name = "", size_t maxShowers = 0):
410  name(new_name), MaxShowers(maxShowers) { Clear(); }
411 
412  std::string Name() const { return name; }
413 
414  void Clear();
415 
416  /// Applies a special prescription to mark shower information as missing
417  void MarkMissing(TTree* pTree);
418  void SetName(std::string new_name) { name = new_name; }
419  void SetMaxShowers(size_t maxShowers)
420  { MaxShowers = maxShowers; Resize(MaxShowers); }
421  void Resize(size_t nShowers);
422  void SetAddresses(TTree* pTree);
423 
424  size_t GetMaxShowers() const { return MaxShowers; }
425  size_t GetMaxPlanesPerShower(int /* iShower */ = 0) const
426  { return (size_t) kNplanes; }
427  size_t GetMaxHitsPerShower(int /* iShower */ = 0, int /* ipl */ = 0) const
428  { return (size_t) kMaxShowerHits; }
429 
430  }; // class ShowerDataStruct
431 
433  public:
434  /* Data structure size:
435  *
436  * PFParticleData_t<Short_t> : 2 bytes/PFParticle
437  * PFParticleData_t<Int_t> : 4 bytes/PFParticle
438  * DaughterData_t<Short_t> : 20 bytes/PFParticle
439  * ClusterData_t<Short_t> : 20 bytes/PFParticle
440  * Short_t [kMaxNPFPNeutrinos] : 10 bytes in total
441  */
442  template <typename T>
443  using PFParticleData_t = std::vector<T>;
444  template <typename T>
445  using DaughterData_t = std::vector<BoxedArray<T[kMaxNDaughtersPerPFP]>>;
446  template <typename T>
447  using ClusterData_t = std::vector<BoxedArray<T[kMaxNClustersPerPFP]>>;
448 
449  size_t MaxPFParticles; ///< maximum number of storable PFParticles
450 
451  /// @{
452  /// @name Branch data structures
453  Short_t nPFParticles; ///< the total number of PFParticles
454  PFParticleData_t<Short_t> pfp_selfID; ///< the PFParticles' own IDs
455  PFParticleData_t<Short_t> pfp_isPrimary; ///< whether the PFParticle is a primary particle
456 
457  PFParticleData_t<Short_t> pfp_numDaughters; ///< the number of daughters belonging to this PFParticle
458  DaughterData_t<Short_t> pfp_daughterIDs; ///< the IDs of the daughter PFParticles
459  PFParticleData_t<Short_t> pfp_parentID; ///< the ID of this PFParticle's immediate parent
460 
461  PFParticleData_t<Short_t> pfp_vertexID; ///< the ID of the vertex belonging to this PFParticle
462  PFParticleData_t<Short_t> pfp_isShower; ///< whether this PFParticle corresponds to a shower
463  PFParticleData_t<Short_t> pfp_isTrack; ///< whether this PFParticle corresponds to a track
464  PFParticleData_t<Short_t> pfp_trackID; ///< the ID of the track object corresponding to this PFParticle, if !isShower
465  PFParticleData_t<Short_t> pfp_showerID; ///< the ID of the shower object corresponding to this PFParticle, if isShower
466 
467  PFParticleData_t<Short_t> pfp_isNeutrino; ///< whether this PFParticle is a neutrino
468  PFParticleData_t<Int_t> pfp_pdgCode; ///< the preliminary estimate of the PFParticle type using the PDG code
469 
470  PFParticleData_t<Short_t> pfp_numClusters; ///< the number of associated clusters
471  ClusterData_t<Short_t> pfp_clusterIDs; ///< the IDs of any associated clusters
472 
473  Short_t pfp_numNeutrinos; ///< the number of reconstructed neutrinos
474  Short_t pfp_neutrinoIDs[kMaxNPFPNeutrinos]; ///< the PFParticle IDs of the neutrinos
475  /// @}
476 
477  /// Creates a PFParticle data structure allowing up to maxPFParticles PFParticles
478  PFParticleDataStruct(size_t maxPFParticles = 0):
479  MaxPFParticles(maxPFParticles) { Clear(); }
480 
481  void Clear();
482  void SetMaxPFParticles(size_t maxPFParticles)
483  { MaxPFParticles = maxPFParticles; Resize(MaxPFParticles); }
484  void Resize(size_t numPFParticles);
485  void SetAddresses(TTree* pTree);
486 
487  size_t GetMaxPFParticles() const { return MaxPFParticles; }
488  size_t GetMaxDaughtersPerPFParticle(int /* iPFParticle */ = 0) const
489  { return (size_t) kMaxNDaughtersPerPFP; }
490  size_t GetMaxClustersPerPFParticle(int /* iPFParticle */ = 0) const
491  { return (size_t) kMaxNClustersPerPFP; }
492 
493  }; // class PFParticleDataStruct
494 
495  enum DataBits_t: unsigned int {
496  tdAuxDet = 0x01,
497  tdCry = 0x02,
498  tdGenie = 0x04,
499  tdPhotons = 0x08,
500  tdGenerator = 0x10,
501  tdGeant = 0x20,
502  tdGeantInAV = 0x40,
503  tdGeantTrajectory = 0x80,
504  tdSimEnergyDepositTPCActive = 0x100,
505  tdHit = 0x200,
506  tdTrack = 0x400,
507  tdVertex = 0x800,
508  tdFlash = 0x1000,
509  tdShower = 0x2000,
510  tdMCshwr = 0x4000,
511  tdMCtrk = 0x8000,
512  tdCluster = 0x10000,
513  tdRawDigit = 0x20000,
514  tdRecobWire = 0x40000,
515  tdPandoraNuVertex = 0x80000,
516  tdPFParticle = 0x100000,
517  tdCount = 0x200000,
518  tdProto = 0x400000,
519  tdDefault = 0
520  }; // DataBits_t
521 
522  /* /// information from the run
523  struct RunData_t {
524  public:
525  RunData_t() { Clear(); }
526  void Clear() {}
527  }; // struct RunData_t
528  */
529  /// information from the subrun
530  struct SubRunData_t {
531  SubRunData_t() { Clear(); }
532  void Clear() {
533  pot = -999.;
534  potbnbETOR860 = -999.;
535  potbnbETOR875 = -999.;
536  potnumiETORTGT = -999.;
537  }
538  Double_t pot; //protons on target
539  Double_t potbnbETOR860;
540  Double_t potbnbETOR875;
541  Double_t potnumiETORTGT;
542  }; // struct SubRunData_t
543 
544  // RunData_t RunData; ///< run data collected at begin of run
545  SubRunData_t SubRunData; ///< subrun data collected at begin of subrun
546 
547  //run information
548  Int_t run; //run number
549  Int_t subrun; //subrun number
550  Int_t event; //event number
551  Int_t evttime_seconds; //event time in seconds
552  Int_t evttime_nanoseconds; //event time in nanoseconcds
553  Double_t beamtime; //beam time
554  Double_t pot; //protons on target moved in subrun data
555  Double_t taulife; //electron lifetime
556  Char_t isdata; //flag, 0=MC 1=data
557  unsigned int triggernumber; //trigger counter
558  Double_t triggertime; //trigger time w.r.t. electronics clock T0
559  Double_t beamgatetime; //beamgate time w.r.t. electronics clock T0
560  unsigned int triggerbits; //trigger bits
561  Double_t potbnb; //pot per event (BNB E:TOR860)
562  Double_t potnumitgt; //pot per event (NuMI E:TORTGT)
563  Double_t potnumi101; //pot per event (NuMI E:TOR101)
564 
565  // hit information (non-resizeable, 45x kMaxHits = 900k bytes worth)
566  Int_t no_hits; //number of hits
567  Int_t NHitsInAllTracks; //number of hits in all tracks
568  Int_t no_hits_stored; //number of hits actually stored in the tree
569  Short_t hit_tpc[kMaxHits]; //tpc number
570  Short_t hit_view[kMaxHits]; //plane number
571  Short_t hit_wire[kMaxHits]; //wire number
572  Short_t hit_channel[kMaxHits]; //channel ID
573  Float_t hit_peakT[kMaxHits]; //peak time
574  Float_t hit_chargesum[kMaxHits]; //charge (sum)
575  Float_t hit_chargeintegral[kMaxHits]; //charge (integral)
576  Float_t hit_ph[kMaxHits]; //amplitude
577  Float_t hit_startT[kMaxHits]; //hit start time
578  Float_t hit_endT[kMaxHits]; //hit end time
579  Float_t hit_rms[kMaxHits]; //hit rms from the hit object
580  Float_t hit_goodnessOfFit[kMaxHits]; //chi2/dof goodness of fit
581  Float_t hit_fitparamampl[kMaxHits]; //dual phase hit fit
582  Float_t hit_fitparamt0[kMaxHits]; //dual phase hit fit
583  Float_t hit_fitparamtau1[kMaxHits]; //dual phase hit fit
584  Float_t hit_fitparamtau2[kMaxHits]; //dual phase hit fit
585  Short_t hit_multiplicity[kMaxHits]; //multiplicity of the given hit
586  Int_t hit_trueID[kMaxHits]; //true mctackID form backtracker
587  Float_t hit_trueEnergyMax[kMaxHits]; //energy deposited from that mctrackID
588  Float_t hit_trueEnergyFraction[kMaxHits]; //maxe/tote
589  // Float_t hit_trueX[kMaxHits]; // hit true X (cm)
590  // Float_t hit_nelec[kMaxHits]; //hit number of electrons
591  // Float_t hit_energy[kMaxHits]; //hit energy
592  Short_t hit_trkid[kMaxHits]; //is this hit associated with a reco track?
593  // Short_t hit_trkKey[kMaxHits]; //is this hit associated with a reco track, if so associate a unique track key ID?
594  Short_t hit_clusterid[kMaxHits]; //is this hit associated with a reco cluster?
595  // Short_t hit_clusterKey[kMaxHits]; //is this hit associated with a reco cluster, if so associate a unique cluster key ID?
596 /*
597  Float_t rawD_ph[kMaxHits];
598  Float_t rawD_peakT[kMaxHits];
599  Float_t rawD_charge[kMaxHits];
600  Float_t rawD_fwhh[kMaxHits];
601  Double_t rawD_rms[kMaxHits];
602 */
603  Int_t no_channels; //number of readout channels with raw waveform (can be different from number of max channels in simulation)
604  Int_t no_ticks; //number of readout ticks for raw waveform
605  Int_t no_ticksinallchannels; //number of readout ticks multiplied by no_channels
606 
607  Int_t rawD_Channel[kMaxChannels];
608  Short_t rawD_ADC[kMaxReadoutTicksInAllChannels];
609 
610  Int_t no_recochannels; //number of readout channels with "reco" waveform (can be different from number of max channels in simulation)
611  Int_t recoW_Channel[kMaxChannels];
612  Int_t recoW_NTicks[kMaxChannels];
613 
614  Int_t no_recoticksinallchannels; //number of readout ticks multiplied by no_channels
615  Int_t recoW_Tick[kMaxReadoutTicksInAllChannels];
616  Float_t recoW_ADC[kMaxReadoutTicksInAllChannels];
617 
618  //Light information
619  size_t MaxPhotons = 0;
621  std::vector<Float_t> photons_time;
622  std::vector<Float_t> photons_channel;
623 
624  //Pandora Nu Vertex information
625  Short_t nnuvtx;
626  Float_t nuvtxx[kMaxVertices];
627  Float_t nuvtxy[kMaxVertices];
628  Float_t nuvtxz[kMaxVertices];
629  Short_t nuvtxpdg[kMaxVertices];
630 
631  //Cluster Information
632  Short_t nclusters; //number of clusters in a given event
633  Short_t clusterId[kMaxClusters]; //ID of this cluster
634  Short_t clusterView[kMaxClusters]; //which plane this cluster belongs to
635  Int_t cluster_isValid[kMaxClusters]; //is this cluster valid? will have a value of -1 if it is not valid
636  Float_t cluster_StartCharge[kMaxClusters]; //charge on the first wire of the cluster in ADC
637  Float_t cluster_StartAngle[kMaxClusters]; //starting angle of the cluster
638  Float_t cluster_EndCharge[kMaxClusters]; //charge on the last wire of the cluster in ADC
639  Float_t cluster_EndAngle[kMaxClusters]; //ending angle of the cluster
640  Float_t cluster_Integral[kMaxClusters]; //returns the total charge of the cluster from hit shape in ADC
641  Float_t cluster_IntegralAverage[kMaxClusters]; //average charge of the cluster hits in ADC
642  Float_t cluster_SummedADC[kMaxClusters]; //total charge of the cluster from signal ADC counts
643  Float_t cluster_SummedADCaverage[kMaxClusters]; //average signal ADC counts of the cluster hits.
644  Float_t cluster_MultipleHitDensity[kMaxClusters]; //Density of wires in the cluster with more than one hit.
645  Float_t cluster_Width[kMaxClusters]; //cluster width in ? units
646  Short_t cluster_NHits[kMaxClusters]; //Number of hits in the cluster
647  Short_t cluster_StartWire[kMaxClusters]; //wire coordinate of the start of the cluster
648  Short_t cluster_StartTick[kMaxClusters]; //tick coordinate of the start of the cluster in time ticks
649  Short_t cluster_EndWire[kMaxClusters]; //wire coordinate of the end of the cluster
650  Short_t cluster_EndTick[kMaxClusters]; //tick coordinate of the end of the cluster in time ticks
651  //Cluster cosmic tagging information
652  // Short_t cluncosmictags_tagger[kMaxClusters]; //No. of cosmic tags associated to this cluster
653  // Float_t clucosmicscore_tagger[kMaxClusters]; //Cosmic score associated to this cluster. In the case of more than one tag, the first one is associated.
654  // Short_t clucosmictype_tagger[kMaxClusters]; //Cosmic tag type for this cluster.
655 
656  // flash information
657  Int_t no_flashes; //number of flashes
658  Float_t flash_time[kMaxFlashes]; //flash time
659  Float_t flash_pe[kMaxFlashes]; //flash total PE
660  Float_t flash_ycenter[kMaxFlashes];//y center of flash
661  Float_t flash_zcenter[kMaxFlashes];//z center of flash
662  Float_t flash_ywidth[kMaxFlashes]; //y width of flash
663  Float_t flash_zwidth[kMaxFlashes]; //z width of flash
664  Float_t flash_timewidth[kMaxFlashes]; //time of flash
665 
666  // External Counter information
667  Int_t no_ExternCounts; // Number of External Triggers
668  Float_t externcounts_time[kMaxExternCounts]; // Time of External Trigger
669  Float_t externcounts_id[kMaxExternCounts]; // ID of External Trigger
670 
671  //track information
672  Char_t kNTracker;
673  std::vector<TrackDataStruct> TrackData;
674 
675  //vertex information
677  std::vector<VertexDataStruct> VertexData;
678 
679  // shower information
681  std::vector<ShowerDataStruct> ShowerData;
682 
683  // PFParticle information
685 
686  //mctruth information
687  Int_t mcevts_truth; //number of neutrino Int_teractions in the spill
688  Int_t nuPDG_truth[kMaxTruth]; //neutrino PDG code
689  Int_t ccnc_truth[kMaxTruth]; //0=CC 1=NC
690  Int_t mode_truth[kMaxTruth]; //0=QE/El, 1=RES, 2=DIS, 3=Coherent production
691  Float_t enu_truth[kMaxTruth]; //true neutrino energy
692  Float_t Q2_truth[kMaxTruth]; //Momentum transfer squared
693  Float_t W_truth[kMaxTruth]; //hadronic invariant mass
694  Float_t X_truth[kMaxTruth];
695  Float_t Y_truth[kMaxTruth];
696  Int_t hitnuc_truth[kMaxTruth]; //hit nucleon
697  Float_t nuvtxx_truth[kMaxTruth]; //neutrino vertex x
698  Float_t nuvtxy_truth[kMaxTruth]; //neutrino vertex y
699  Float_t nuvtxz_truth[kMaxTruth]; //neutrino vertex z
700  Float_t nu_dcosx_truth[kMaxTruth]; //neutrino dcos x
701  Float_t nu_dcosy_truth[kMaxTruth]; //neutrino dcos y
702  Float_t nu_dcosz_truth[kMaxTruth]; //neutrino dcos z
703  Float_t lep_mom_truth[kMaxTruth]; //lepton momentum
704  Float_t lep_dcosx_truth[kMaxTruth]; //lepton dcos x
705  Float_t lep_dcosy_truth[kMaxTruth]; //lepton dcos y
706  Float_t lep_dcosz_truth[kMaxTruth]; //lepton dcos z
707 
708  //flux information
709  Float_t vx_flux[kMaxTruth]; //X position of hadron/muon decay (cm)
710  Float_t vy_flux[kMaxTruth]; //Y position of hadron/muon decay (cm)
711  Float_t vz_flux[kMaxTruth]; //Z position of hadron/muon decay (cm)
712  Float_t pdpx_flux[kMaxTruth]; //Parent X momentum at decay point (GeV)
713  Float_t pdpy_flux[kMaxTruth]; //Parent Y momentum at decay point (GeV)
714  Float_t pdpz_flux[kMaxTruth]; //Parent Z momentum at decay point (GeV)
715  Float_t ppdxdz_flux[kMaxTruth]; //Parent dxdz direction at production
716  Float_t ppdydz_flux[kMaxTruth]; //Parent dydz direction at production
717  Float_t pppz_flux[kMaxTruth]; //Parent Z momentum at production (GeV)
718 
719  Int_t ptype_flux[kMaxTruth]; //Parent GEANT code particle ID
720  Float_t ppvx_flux[kMaxTruth]; //Parent production vertex X (cm)
721  Float_t ppvy_flux[kMaxTruth]; //Parent production vertex Y (cm)
722  Float_t ppvz_flux[kMaxTruth]; //Parent production vertex Z (cm)
723  Float_t muparpx_flux[kMaxTruth]; //Muon neutrino parent production vertex X (cm)
724  Float_t muparpy_flux[kMaxTruth]; //Muon neutrino parent production vertex Y (cm)
725  Float_t muparpz_flux[kMaxTruth]; //Muon neutrino parent production vertex Z (cm)
726  Float_t mupare_flux[kMaxTruth]; //Muon neutrino parent energy (GeV)
727 
728  Int_t tgen_flux[kMaxTruth]; //Parent generation in cascade. (1 = primary proton,
729  //2=particles produced by proton interaction, 3 = particles
730  //produced by interactions of the 2's, ...
731  Int_t tgptype_flux[kMaxTruth]; //Type of particle that created a particle flying of the target
732  Float_t tgppx_flux[kMaxTruth]; //X Momentum of a particle, that created a particle that flies
733  //off the target, at the interaction point. (GeV)
734  Float_t tgppy_flux[kMaxTruth]; //Y Momentum of a particle, that created a particle that flies
735  //off the target, at the interaction point. (GeV)
736  Float_t tgppz_flux[kMaxTruth]; //Z Momentum of a particle, that created a particle that flies
737  //off the target, at the interaction point. (GeV)
738  Float_t tprivx_flux[kMaxTruth]; //Primary particle interaction vertex X (cm)
739  Float_t tprivy_flux[kMaxTruth]; //Primary particle interaction vertex Y (cm)
740  Float_t tprivz_flux[kMaxTruth]; //Primary particle interaction vertex Z (cm)
741  Float_t dk2gen_flux[kMaxTruth]; //distance from decay to ray origin (cm)
742  Float_t gen2vtx_flux[kMaxTruth]; //distance from ray origin to event vtx (cm)
743 
744  Float_t tpx_flux[kMaxTruth]; //Px of parent particle leaving BNB/NuMI target (GeV)
745  Float_t tpy_flux[kMaxTruth]; //Py of parent particle leaving BNB/NuMI target (GeV)
746  Float_t tpz_flux[kMaxTruth]; //Pz of parent particle leaving BNB/NuMI target (GeV)
747  Int_t tptype_flux[kMaxTruth]; //Type of parent particle leaving BNB target
748 
749  //genie information
750  size_t MaxGeniePrimaries = 0;
752  std::vector<Int_t> genie_primaries_pdg;
753  std::vector<Float_t> genie_Eng;
754  std::vector<Float_t> genie_Px;
755  std::vector<Float_t> genie_Py;
756  std::vector<Float_t> genie_Pz;
757  std::vector<Float_t> genie_P;
758  std::vector<Int_t> genie_status_code;
759  std::vector<Float_t> genie_mass;
760  std::vector<Int_t> genie_trackID;
761  std::vector<Int_t> genie_ND;
762  std::vector<Int_t> genie_mother;
763 
764  //cosmic cry information
765  Int_t mcevts_truthcry; //number of neutrino Int_teractions in the spill
767  std::vector<Int_t> cry_primaries_pdg;
768  std::vector<Float_t> cry_Eng;
769  std::vector<Float_t> cry_Px;
770  std::vector<Float_t> cry_Py;
771  std::vector<Float_t> cry_Pz;
772  std::vector<Float_t> cry_P;
773  std::vector<Float_t> cry_StartPointx;
774  std::vector<Float_t> cry_StartPointy;
775  std::vector<Float_t> cry_StartPointz;
776  std::vector<Float_t> cry_StartPointt;
777  std::vector<Int_t> cry_status_code;
778  std::vector<Float_t> cry_mass;
779  std::vector<Int_t> cry_trackID;
780  std::vector<Int_t> cry_ND;
781  std::vector<Int_t> cry_mother;
782 
783  // ProtoDUNE Beam generator information
785  std::vector<Int_t> proto_isGoodParticle;
786  std::vector<Float_t> proto_vx;
787  std::vector<Float_t> proto_vy;
788  std::vector<Float_t> proto_vz;
789  std::vector<Float_t> proto_t;
790  std::vector<Float_t> proto_px;
791  std::vector<Float_t> proto_py;
792  std::vector<Float_t> proto_pz;
793  std::vector<Float_t> proto_momentum;
794  std::vector<Float_t> proto_energy;
795  std::vector<Int_t> proto_pdg;
796 
797  //Generator and G4 MC Particle information
798  size_t MaxGeneratorparticles = 0; ///! how many particles there is currently room for
799  Int_t generator_list_size; //number of all geant particles
800 
801  size_t MaxGEANTparticles = 0; ///! how many particles there is currently room for
802  Int_t no_primaries; //number of primary geant particles
803  Int_t geant_list_size; //number of all geant particles
805  std::vector<Int_t> pdg;
806  std::vector<Int_t> status;
807  std::vector<Int_t> inTPCActive;
808  std::vector<Float_t> Eng;
809  std::vector<Float_t> EndE;
810  std::vector<Float_t> Mass;
811  std::vector<Float_t> Px;
812  std::vector<Float_t> Py;
813  std::vector<Float_t> Pz;
814  std::vector<Float_t> P;
815  std::vector<Float_t> StartPointx;
816  std::vector<Float_t> StartPointy;
817  std::vector<Float_t> StartPointz;
818  std::vector<Float_t> StartT;
819  std::vector<Float_t> EndT;
820  std::vector<Float_t> EndPointx;
821  std::vector<Float_t> EndPointy;
822  std::vector<Float_t> EndPointz;
823  std::vector<Float_t> theta;
824  std::vector<Float_t> phi;
825  std::vector<Float_t> theta_xz;
826  std::vector<Float_t> theta_yz;
827 
828  size_t MaxGEANTInAVparticles = 0;
829  std::vector<Float_t> pathlen_tpcAV;
830  std::vector<Int_t> TrackId_tpcAV;
831  std::vector<Int_t> PDGCode_tpcAV;
832  std::vector<Float_t> StartPointx_tpcAV;
833  std::vector<Float_t> StartPointy_tpcAV;
834  std::vector<Float_t> StartPointz_tpcAV;
835  std::vector<Float_t> StartT_tpcAV;
836  std::vector<Float_t> StartE_tpcAV;
837  std::vector<Float_t> StartP_tpcAV;
838  std::vector<Float_t> StartPx_tpcAV;
839  std::vector<Float_t> StartPy_tpcAV;
840  std::vector<Float_t> StartPz_tpcAV;
841  std::vector<Float_t> thetastart_tpcAV;
842  std::vector<Float_t> phistart_tpcAV;
843  std::vector<Float_t> EndPointx_tpcAV;
844  std::vector<Float_t> EndPointy_tpcAV;
845  std::vector<Float_t> EndPointz_tpcAV;
846  std::vector<Float_t> EndT_tpcAV;
847  std::vector<Float_t> EndE_tpcAV;
848  std::vector<Float_t> EndP_tpcAV;
849  std::vector<Float_t> EndPx_tpcAV;
850  std::vector<Float_t> EndPy_tpcAV;
851  std::vector<Float_t> EndPz_tpcAV;
852  std::vector<Float_t> thetaend_tpcAV;
853  std::vector<Float_t> phiend_tpcAV;
854 
855  std::vector<Float_t> pathlen_drifted;
856  std::vector<Int_t> inTPCDrifted;
857  std::vector<Float_t> StartPointx_drifted;
858  std::vector<Float_t> StartPointy_drifted;
859  std::vector<Float_t> StartPointz_drifted;
860  std::vector<Float_t> StartT_drifted;
861  std::vector<Float_t> StartE_drifted;
862  std::vector<Float_t> StartP_drifted;
863  std::vector<Float_t> StartPx_drifted;
864  std::vector<Float_t> StartPy_drifted;
865  std::vector<Float_t> StartPz_drifted;
866  std::vector<Float_t> EndPointx_drifted;
867  std::vector<Float_t> EndPointy_drifted;
868  std::vector<Float_t> EndPointz_drifted;
869  std::vector<Float_t> EndT_drifted;
870  std::vector<Float_t> EndE_drifted;
871  std::vector<Float_t> EndP_drifted;
872  std::vector<Float_t> EndPx_drifted;
873  std::vector<Float_t> EndPy_drifted;
874  std::vector<Float_t> EndPz_drifted;
875  std::vector<Int_t> NumberDaughters;
876  std::vector<Int_t> TrackId;
877  std::vector<Int_t> Mother;
878  std::vector<Int_t> process_primary;
879  std::vector<std::string> processname;
880  std::vector<Int_t> MergedId; //geant track segments, which belong to the same particle, get the same
881  std::vector<Int_t> origin; ////0: unknown, 1: cosmic, 2: neutrino, 3: supernova, 4: singles
882  std::vector<Int_t> MCTruthIndex; //this geant particle comes from the neutrino interaction of the _truth variables with this index
883 
884  //G4 MC trajectory information
885  size_t MaxGEANTtrajectorypoints = 0; ///! how many trajectory points for all geant particles there is currently room for
886 
887  Int_t geant_trajectory_size; //number of trajectory points for all geant particles
888 
889  std::vector<Int_t> NTrajectoryPointsPerParticle;
890 
891 
892  std::vector<Int_t> TrajTrackId;
893  std::vector<Int_t> TrajPDGCode;
894  std::vector<Float_t> TrajX;
895  std::vector<Float_t> TrajY;
896  std::vector<Float_t> TrajZ;
897  std::vector<Float_t> TrajT;
898  std::vector<Float_t> TrajE;
899  std::vector<Float_t> TrajP;
900  std::vector<Float_t> TrajPx;
901  std::vector<Float_t> TrajPy;
902  std::vector<Float_t> TrajPz;
903  std::vector<Float_t> TrajTheta;
904  std::vector<Float_t> TrajPhi;
905 
906  //SimEnergyDepositInfo
907  size_t MaxSimEnergyDepositsTPCActive = 0; ///! how many sim energy deposits in TPC AV there is currently room for
908  size_t MaxParticlesWithSimEnergyDepositsTPCActive = 0; ///! how many particles with sim energy deposits in TPC AV there is currently room for
909 
910  Int_t simenergydeposit_size; //number of SEDTPCAV for all geant particles
911  Int_t particleswithsimenergydeposit_size; //number of SEDTPCAV for all geant particles
912 
915 
916  std::vector<Int_t> SEDTPCAVTrackID;
917  std::vector<Int_t> SEDTPCAVPDGCode;
918  std::vector<float> SEDTPCAVEnergy;
919  std::vector<Int_t> SEDTPCAVNumPhotons;
920  std::vector<Int_t> SEDTPCAVNumElectrons;
921  std::vector<float> SEDTPCAVLength;
922 
923  std::vector<float> SEDTPCAVStartTime;
924  std::vector<float> SEDTPCAVStartX;
925  std::vector<float> SEDTPCAVStartY;
926  std::vector<float> SEDTPCAVStartZ;
927 
928  std::vector<float> SEDTPCAVMidTime;
929  std::vector<float> SEDTPCAVMidX;
930  std::vector<float> SEDTPCAVMidY;
931  std::vector<float> SEDTPCAVMidZ;
932 
933  std::vector<float> SEDTPCAVEndTime;
934  std::vector<float> SEDTPCAVEndX;
935  std::vector<float> SEDTPCAVEndY;
936  std::vector<float> SEDTPCAVEndZ;
937 
938 
939 
940  //MC Shower information
941  Int_t no_mcshowers; //number of MC Showers in this event.
942  //MC Shower particle information
943  std::vector<Int_t> mcshwr_origin; //MC Shower origin information.
944  std::vector<Int_t> mcshwr_pdg; //MC Shower particle PDG code.
945  std::vector<Int_t> mcshwr_TrackId; //MC Shower particle G4 track ID.
946  std::vector<std::string> mcshwr_Process; //MC Shower particle's creation process.
947  std::vector<Float_t> mcshwr_startX; //MC Shower particle G4 startX
948  std::vector<Float_t> mcshwr_startY; //MC Shower particle G4 startY
949  std::vector<Float_t> mcshwr_startZ; //MC Shower particle G4 startZ
950  std::vector<Float_t> mcshwr_endX; //MC Shower particle G4 endX
951  std::vector<Float_t> mcshwr_endY; //MC Shower particle G4 endY
952  std::vector<Float_t> mcshwr_endZ; //MC Shower particle G4 endZ
953  std::vector<Float_t> mcshwr_CombEngX; //MC Shower Combined energy deposition information, Start Point X Position.
954  std::vector<Float_t> mcshwr_CombEngY; //MC Shower Combined energy deposition information, Start Point Y Position.
955  std::vector<Float_t> mcshwr_CombEngZ; //MC Shower Combined energy deposition information, Start Point Z Position.
956  std::vector<Float_t> mcshwr_CombEngPx; //MC Shower Combined energy deposition information, Momentum X direction.
957  std::vector<Float_t> mcshwr_CombEngPy; //MC Shower Combined energy deposition information, Momentum X direction.
958  std::vector<Float_t> mcshwr_CombEngPz; //MC Shower Combined energy deposition information, Momentum X direction.
959  std::vector<Float_t> mcshwr_CombEngE; //MC Shower Combined energy deposition information, Energy
960  std::vector<Float_t> mcshwr_dEdx; //MC Shower dEdx, MeV/cm
961  std::vector<Float_t> mcshwr_StartDirX; //MC Shower Direction of begining of shower, X direction
962  std::vector<Float_t> mcshwr_StartDirY; //MC Shower Direction of begining of shower, Y direction
963  std::vector<Float_t> mcshwr_StartDirZ; //MC Shower Direction of begining of shower, Z direction
964  std::vector<Int_t> mcshwr_isEngDeposited; //tells whether if this shower deposited energy in the detector or not.
965  //yes = 1; no =0;
966  //MC Shower mother information
967  std::vector<Int_t> mcshwr_Motherpdg; //MC Shower's mother PDG code.
968  std::vector<Int_t> mcshwr_MotherTrkId; //MC Shower's mother G4 track ID.
969  std::vector<std::string> mcshwr_MotherProcess; //MC Shower's mother creation process.
970  std::vector<Float_t> mcshwr_MotherstartX; //MC Shower's mother G4 startX .
971  std::vector<Float_t> mcshwr_MotherstartY; //MC Shower's mother G4 startY .
972  std::vector<Float_t> mcshwr_MotherstartZ; //MC Shower's mother G4 startZ .
973  std::vector<Float_t> mcshwr_MotherendX; //MC Shower's mother G4 endX .
974  std::vector<Float_t> mcshwr_MotherendY; //MC Shower's mother G4 endY .
975  std::vector<Float_t> mcshwr_MotherendZ; //MC Shower's mother G4 endZ .
976  //MC Shower ancestor information
977  std::vector<Int_t> mcshwr_Ancestorpdg; //MC Shower's ancestor PDG code.
978  std::vector<Int_t> mcshwr_AncestorTrkId; //MC Shower's ancestor G4 track ID.
979  std::vector<std::string> mcshwr_AncestorProcess; //MC Shower's ancestor creation process.
980  std::vector<Float_t> mcshwr_AncestorstartX; //MC Shower's ancestor G4 startX
981  std::vector<Float_t> mcshwr_AncestorstartY; //MC Shower's ancestor G4 startY
982  std::vector<Float_t> mcshwr_AncestorstartZ; //MC Shower's ancestor G4 startZ
983  std::vector<Float_t> mcshwr_AncestorendX; //MC Shower's ancestor G4 endX
984  std::vector<Float_t> mcshwr_AncestorendY; //MC Shower's ancestor G4 endY
985  std::vector<Float_t> mcshwr_AncestorendZ; //MC Shower's ancestor G4 endZ
986 
987  //MC track information
988  Int_t no_mctracks; //number of MC tracks in this event.
989  //MC track particle information
990  std::vector<Int_t> mctrk_origin; //MC track origin information.
991  std::vector<Int_t> mctrk_pdg; //MC track particle PDG code.
992  std::vector<Int_t> mctrk_TrackId; //MC track particle G4 track ID.
993  std::vector<std::string> mctrk_Process; //MC track particle's creation process.
994  std::vector<Float_t> mctrk_startX; //MC track particle G4 startX
995  std::vector<Float_t> mctrk_startY; //MC track particle G4 startY
996  std::vector<Float_t> mctrk_startZ; //MC track particle G4 startZ
997  std::vector<Float_t> mctrk_endX; //MC track particle G4 endX
998  std::vector<Float_t> mctrk_endY; //MC track particle G4 endY
999  std::vector<Float_t> mctrk_endZ; //MC track particle G4 endZ
1000  std::vector<Float_t> mctrk_startX_drifted; //MC track particle first step in TPC x
1001  std::vector<Float_t> mctrk_startY_drifted; //MC track particle first step in TPC y
1002  std::vector<Float_t> mctrk_startZ_drifted; //MC track particle first step in TPC z
1003  std::vector<Float_t> mctrk_endX_drifted; //MC track particle last step in TPC x
1004  std::vector<Float_t> mctrk_endY_drifted; //MC track particle last step in TPC y
1005  std::vector<Float_t> mctrk_endZ_drifted; //MC track particle last step in TPC z
1006  std::vector<Float_t> mctrk_len_drifted; //MC track length within TPC
1007  std::vector<Float_t> mctrk_p_drifted; //MC track momentum at start point in TPC
1008  std::vector<Float_t> mctrk_px_drifted; //MC track x momentum at start point in TPC
1009  std::vector<Float_t> mctrk_py_drifted; //MC track y momentum at start point in TPC
1010  std::vector<Float_t> mctrk_pz_drifted; //MC track z momentum at start point in TPC
1011  //MC Track mother information
1012  std::vector<Int_t> mctrk_Motherpdg; //MC Track's mother PDG code.
1013  std::vector<Int_t> mctrk_MotherTrkId; //MC Track's mother G4 track ID.
1014  std::vector<std::string> mctrk_MotherProcess; //MC Track's mother creation process.
1015  std::vector<Float_t> mctrk_MotherstartX; //MC Track's mother G4 startX .
1016  std::vector<Float_t> mctrk_MotherstartY; //MC Track's mother G4 startY .
1017  std::vector<Float_t> mctrk_MotherstartZ; //MC Track's mother G4 startZ .
1018  std::vector<Float_t> mctrk_MotherendX; //MC Track's mother G4 endX .
1019  std::vector<Float_t> mctrk_MotherendY; //MC Track's mother G4 endY .
1020  std::vector<Float_t> mctrk_MotherendZ; //MC Track's mother G4 endZ .
1021  //MC Track ancestor information
1022  std::vector<Int_t> mctrk_Ancestorpdg; //MC Track's ancestor PDG code.
1023  std::vector<Int_t> mctrk_AncestorTrkId; //MC Track's ancestor G4 track ID.
1024  std::vector<std::string> mctrk_AncestorProcess; //MC Track's ancestor creation process.
1025  std::vector<Float_t> mctrk_AncestorstartX; //MC Track's ancestor G4 startX
1026  std::vector<Float_t> mctrk_AncestorstartY; //MC Track's ancestor G4 startY
1027  std::vector<Float_t> mctrk_AncestorstartZ; //MC Track's ancestor G4 startZ
1028  std::vector<Float_t> mctrk_AncestorendX; //MC Track's ancestor G4 endX
1029  std::vector<Float_t> mctrk_AncestorendY; //MC Track's ancestor G4 endY
1030  std::vector<Float_t> mctrk_AncestorendZ; //MC Track's ancestor G4 endZ
1031 
1032  // Auxiliary detector variables saved for each geant track
1033  // This data is saved as a vector (one item per GEANT particle) of C arrays
1034  // (wrapped in a BoxedArray for technical reasons), one item for each
1035  // affected detector cell (which one is saved in AuxDetID
1036  template <typename T>
1037  using AuxDetMCData_t = std::vector<BoxedArray<T[kMaxAuxDets]>>;
1038 
1039  std::vector<UShort_t> NAuxDets; ///< Number of AuxDets crossed by this particle
1040  AuxDetMCData_t<Short_t> AuxDetID; ///< Which AuxDet this particle went through
1041  AuxDetMCData_t<Float_t> entryX; ///< Entry X position of particle into AuxDet
1042  AuxDetMCData_t<Float_t> entryY; ///< Entry Y position of particle into AuxDet
1043  AuxDetMCData_t<Float_t> entryZ; ///< Entry Z position of particle into AuxDet
1044  AuxDetMCData_t<Float_t> entryT; ///< Entry T position of particle into AuxDet
1045  AuxDetMCData_t<Float_t> exitX; ///< Exit X position of particle out of AuxDet
1046  AuxDetMCData_t<Float_t> exitY; ///< Exit Y position of particle out of AuxDet
1047  AuxDetMCData_t<Float_t> exitZ; ///< Exit Z position of particle out of AuxDet
1048  AuxDetMCData_t<Float_t> exitT; ///< Exit T position of particle out of AuxDet
1049  AuxDetMCData_t<Float_t> exitPx; ///< Exit x momentum of particle out of AuxDet
1050  AuxDetMCData_t<Float_t> exitPy; ///< Exit y momentum of particle out of AuxDet
1051  AuxDetMCData_t<Float_t> exitPz; ///< Exit z momentum of particle out of AuxDet
1052  AuxDetMCData_t<Float_t> CombinedEnergyDep; ///< Sum energy of all particles with this trackID (+ID or -ID) in AuxDet
1053 
1054  unsigned int bits; ///< complementary information
1055 
1056  /// Returns whether we have auxiliary detector data
1057  bool hasAuxDetector() const { return bits & tdAuxDet; }
1058 
1059  /// Returns whether we have Cry data
1060  bool hasCryInfo() const { return bits & tdCry; }
1061 
1062  /// Returns whether we have Genie data
1063  bool hasGenieInfo() const { return bits & tdGenie; }
1064 
1065  /// Returns whether we have MCShower data
1066  bool hasMCShowerInfo() const { return bits & tdMCshwr; }
1067 
1068  /// Returns whether we have MCTrack data
1069  bool hasMCTrackInfo() const { return bits & tdMCtrk; }
1070 
1071  /// Returns whether we have Hit data
1072  bool hasHitInfo() const { return bits & tdHit; }
1073 
1074  /// Returns whether we have RawDigit data
1075  bool hasRawDigitInfo() const { return bits & tdRawDigit; }
1076 
1077  /// Returns whether we have RecobWire data
1078  bool hasRecobWireInfo() const { return bits & tdRecobWire; }
1079 
1080  /// Returns whether we have Track data
1081  bool hasTrackInfo() const { return bits & tdTrack; }
1082 
1083  /// Returns whether we have Shower data
1084  bool hasShowerInfo() const { return bits & tdShower; }
1085 
1086  /// Returns whether we have Vertex data
1087  bool hasVertexInfo() const { return bits & tdVertex; }
1088 
1089  /// Returns whether we have PFParticle data
1090  bool hasPFParticleInfo() const { return bits & tdPFParticle; }
1091 
1092  /// Returns whether we have Cluster data
1093  bool hasClusterInfo() const { return bits & tdCluster; }
1094 
1095  /// Returns whether we have Pandora Nu Vertex data
1096  bool hasPandoraNuVertexInfo() const { return bits & tdPandoraNuVertex; }
1097 
1098  /// Returns whether we have photon data
1099  bool hasPhotonInfo() const { return bits & tdPhotons; }
1100 
1101  /// Returns whether we have Generator data
1102  bool hasGeneratorInfo() const { return bits & tdGenerator; }
1103 
1104  /// Returns whether we have Geant data
1105  bool hasGeantInfo() const { return bits & tdGeant; }
1106 
1107  /// Returns whether we have Geant data
1108  bool hasGeantInAVInfo() const { return bits & tdGeantInAV; }
1109 
1110  /// Returns whether we have Geant trajectory data
1111  bool hasGeantTrajectoryInfo() const { return bits & tdGeantTrajectory; }
1112 
1113  /// Returns whether we have Geant trajectory data
1114  bool hasSimEnergyDepositTPCActiveInfo() const { return bits & tdSimEnergyDepositTPCActive; }
1115 
1116  /// Returns whether we have Flash data
1117  bool hasFlashInfo() const { return bits & tdFlash; }
1118 
1119  /// Returns whether we have External Counter data
1120  bool hasExternCountInfo() const { return bits & tdCount; }
1121 
1122  /// Returns whether we have protoDUNE beam primaries
1123  bool hasProtoInfo() const {return bits & tdProto; }
1124 
1125  /// Sets the specified bits
1126  void SetBits(unsigned int setbits, bool unset = false)
1127  { if (unset) bits &= ~setbits; else bits |= setbits; }
1128 
1129  /// Constructor; clears all fields
1130  AnaRootParserDataStruct(size_t nTrackers = 0, size_t nVertexAlgos = 0,
1131  std::vector<std::string> const& ShowerAlgos = {}):
1132  bits(tdDefault)
1133  { SetTrackers(nTrackers); SetVertexAlgos(nVertexAlgos); SetShowerAlgos(ShowerAlgos); Clear(); }
1134 
1136  { return TrackData.at(iTracker); }
1137  const TrackDataStruct& GetTrackerData(size_t iTracker) const
1138  { return TrackData.at(iTracker); }
1139 
1141  { return ShowerData.at(iShower); }
1142  ShowerDataStruct const& GetShowerData(size_t iShower) const
1143  { return ShowerData.at(iShower); }
1144 
1146  { return VertexData.at(iVertex); }
1147  const VertexDataStruct& GetVertexData(size_t iVertex) const
1148  { return VertexData.at(iVertex); }
1149 
1151  { return PFParticleData; }
1153  { return PFParticleData; }
1154 
1155  /// Clear all fields if this object (not the tracker algorithm data)
1156  void ClearLocalData();
1157 
1158  /// Clear all fields
1159  void Clear();
1160 
1161 
1162  /// Allocates data structures for the given number of trackers (no Clear())
1163  void SetTrackers(size_t nTrackers) { TrackData.resize(nTrackers); }
1164 
1165  /// Allocates data structures for the given number of vertex algos (no Clear())
1166  void SetVertexAlgos(size_t nVertexAlgos) { VertexData.resize(nVertexAlgos); }
1167 
1168  /// Allocates data structures for the given number of trackers (no Clear())
1169  void SetShowerAlgos(std::vector<std::string> const& ShowerAlgos);
1170 
1171  /// Resize the data strutcure for Generator particles
1172  void ResizePhotons(int nPhotons);
1173 
1174  /// Resize the data strutcure for Generator particles
1175  void ResizeGenerator(int nParticles);
1176 
1177  /// Resize the data strutcure for GEANT particles
1178  void ResizeGEANT(int nParticles);
1179 
1180  /// Resize the data strutcure for GEANT particles in active volume
1181  void ResizeGEANTInAV(int nParticlesInAV);
1182 
1183  /// Resize the data strutcure for GEANT trajectory info
1184  void ResizeGEANTTrajectory(int nTrajectoryPoints);
1185 
1186  /// Resize the data strutcure for SimEnergyDepositTPCActive info
1187  void ResizeSimEnergyDepositsTPCActive(int nSimEnergyDepositsTPCActive, int nParticlesWithSimEnergyDepositsTPCActive);
1188 
1189  /// Resize the data strutcure for Genie primaries
1190  void ResizeGenie(int nPrimaries);
1191 
1192  /// Resize the data strutcure for Cry primaries
1193  void ResizeCry(int nPrimaries);
1194 
1195  /// Resize the data structure for ProtoDUNE primaries
1196  void ResizeProto(int nPrimaries);
1197 
1198  /// Resize the data strutcure for MC Showers
1199  void ResizeMCShower(int nMCShowers);
1200 
1201  /// Resize the data strutcure for MC Tracks
1202  void ResizeMCTrack(int nMCTracks);
1203 
1204  /// Connect this object with a tree
1205  void SetAddresses(
1206  TTree* pTree,
1207  std::vector<std::string> const& trackers,
1208  std::vector<std::string> const& vertexalgos,
1209  std::vector<std::string> const& showeralgos,
1210  bool isCosmics
1211  );
1212 
1213 
1214  /// Returns the number of trackers for which data structures are allocated
1215  size_t GetNTrackers() const { return TrackData.size(); }
1216 
1217  /// Returns the number of Vertex algos for which data structures are allocated
1218  size_t GetNVertexAlgos() const { return VertexData.size(); }
1219 
1220  /// Returns the number of trackers for which data structures are allocated
1221  size_t GetNShowerAlgos() const { return ShowerData.size(); }
1222 
1223  /// Returns the number of hits for which memory is allocated
1224  size_t GetMaxHits() const { return kMaxHits; }
1225 
1226  /// Returns the number of trackers for which memory is allocated
1227  size_t GetMaxTrackers() const { return TrackData.capacity(); }
1228 
1229  /// Returns the number of trackers for which memory is allocated
1230  size_t GetMaxVertexAlgos() const { return VertexData.capacity(); }
1231 
1232  /// Returns the number of trackers for which memory is allocated
1233  size_t GetMaxShowers() const { return ShowerData.capacity(); }
1234 
1235  /// Returns the number of GEANT particles for which memory is allocated
1236  size_t GetMaxPhotons() const { return MaxPhotons; }
1237 
1238  /// Returns the number of GEANT particles for which memory is allocated
1239  size_t GetMaxGeneratorparticles() const { return MaxGeneratorparticles; }
1240 
1241  /// Returns the number of GEANT particles for which memory is allocated
1242  size_t GetMaxGEANTparticles() const { return MaxGEANTparticles; }
1243 
1244  /// Returns the number of GEANT particles in AV for which memory is allocated
1245  size_t GetMaxGEANTInAVparticles() const { return MaxGEANTInAVparticles; }
1246 
1247  /// Returns the number of GEANT trajectory steps for which memory is allocated
1248  size_t GetMaxGEANTtrajectorypoints() const { return MaxGEANTtrajectorypoints; }
1249 
1250  /// Returns the number of SimEnergyDepositsTPCActive for which memory is allocated
1251  size_t GetMaxSimEnergyDepositsTPCActive() const { return MaxSimEnergyDepositsTPCActive; }
1252 
1253  /// Returns the number of particles with SimEnergyDepositsTPCActive for which memory is allocated
1254  size_t GetMaxParticlesWithSimEnergyDepositsTPCActive() const { return MaxParticlesWithSimEnergyDepositsTPCActive; }
1255 
1256 
1257 
1258  /// Returns the number of GENIE primaries for which memory is allocated
1259  size_t GetMaxGeniePrimaries() const { return MaxGeniePrimaries; }
1260 
1261 
1262  private:
1263  /// Little helper functor class to create or reset branches in a tree
1265  public:
1266  TTree* pTree; ///< the tree to be worked on
1267  BranchCreator(TTree* tree): pTree(tree) {}
1268 
1269  //@{
1270  /// Create a branch if it does not exist, and set its address
1271  void operator()
1272  (std::string name, void* address, std::string leaflist /*, int bufsize = 32000 */)
1273  {
1274 
1275  if (!pTree) return;
1276  TBranch* pBranch = pTree->GetBranch(name.c_str());
1277 
1278  if (!pBranch) {
1279  pTree->Branch(name.c_str(), address, leaflist.c_str() /*, bufsize */);
1280 
1281  MF_LOG_DEBUG("AnaRootParserStructure")
1282  << "Creating branch '" << name << " with leaf '" << leaflist << "'";
1283 
1284  }
1285  else if (pBranch->GetAddress() != address) {
1286  pBranch->SetAddress(address);
1287  MF_LOG_DEBUG("AnaRootParserStructure")
1288  << "Reassigning address to branch '" << name << "'";
1289  }
1290  else {
1291  MF_LOG_DEBUG("AnaRootParserStructure")
1292  << "Branch '" << name << "' is fine";
1293  }
1294  } // operator()
1295  void operator()
1296  (std::string name, void* address, const std::stringstream& leaflist /*, int bufsize = 32000 */)
1297  { return this->operator() (name, address, leaflist.str() /*, int bufsize = 32000 */); }
1298  template <typename T>
1299  void operator()
1300  (std::string name, std::vector<T>& data, std::string leaflist /*, int bufsize = 32000 */)
1301  { return this->operator() (name, (void*) data.data(), leaflist /*, int bufsize = 32000 */); }
1302 
1303  template <typename T>
1304  void operator() (std::string name, std::vector<T>& data)
1305  {
1306  // overload for a generic object expressed directly by reference
1307  // (as opposed to a generic object expressed by a pointer or
1308  // to a simple leaf sequence specification);
1309  // TTree::Branch(name, T* obj, Int_t bufsize, splitlevel) and
1310  // TTree::SetObject() are used.
1311  if (!pTree) return;
1312  TBranch* pBranch = pTree->GetBranch(name.c_str());
1313  if (!pBranch) {
1314  pTree->Branch(name.c_str(), &data);
1315  // ROOT needs a TClass definition for T in order to create a branch,
1316  // se we are sure that at this point the TClass exists
1317  MF_LOG_DEBUG("AnaRootParserStructure")
1318  << "Creating object branch '" << name
1319  << " with " << TClass::GetClass(typeid(T))->ClassName();
1320  }
1321  else if
1322  (*(reinterpret_cast<std::vector<T>**>(pBranch->GetAddress())) != &data)
1323  {
1324  // when an object is provided directly, the address of the object
1325  // is assigned in TBranchElement::fObject (via TObject::SetObject())
1326  // and the address itself is set to the address of the fObject
1327  // member. Here we check that the address of the object in fObject
1328  // is the same as the address of our current data type
1329  pBranch->SetObject(&data);
1330  MF_LOG_DEBUG("AnaRootParserStructure")
1331  << "Reassigning object to branch '" << name << "'";
1332  }
1333  else {
1334  MF_LOG_DEBUG("AnaRootParserStructure")
1335  << "Branch '" << name << "' is fine";
1336  }
1337  } // operator()
1338  //@}
1339  }; // class BranchCreator
1340 
1341  }; // class AnaRootParserDataStruct
1342 
1343 
1344  /// Contains ROOTTreeCode<>::code, ROOT tree character for branch of type T
1345  template <typename T> struct ROOTTreeCode; // generally undefined
1346 
1347  template<> struct ROOTTreeCode<Short_t> { static constexpr char code = 'S'; };
1348  template<> struct ROOTTreeCode<Int_t> { static constexpr char code = 'I'; };
1349  template<> struct ROOTTreeCode<Double_t> { static constexpr char code = 'D'; };
1350 
1351 
1352  /// Class whose "type" contains the base data type of the container
1353  template <typename C> struct ContainerValueType; // generally undefined
1354 
1355  template <typename A>
1356  struct ContainerValueType<std::vector<AnaRootParserDataStruct::BoxedArray<A>>>
1358 
1359  template <typename T>
1360  struct ContainerValueType<std::vector<T>>
1361  { using type = typename std::vector<T>::value_type; };
1362 
1363 
1364  /**
1365  * @brief Creates a simple ROOT tree with tracking and calorimetry information
1366  *
1367  * <h2>Configuration parameters</h2>
1368  * - <b>UseBuffers</b> (default: false): if enabled, memory is allocated for
1369  * tree data for all the run; otherwise, it's allocated on each event, used
1370  * and freed; use "true" for speed, "false" to save memory
1371  * - <b>SaveAuxDetInfo</b> (default: false): if enabled, auxiliary detector
1372  * data will be extracted and included in the tree
1373  */
1375 
1376  public:
1377 
1378  explicit AnaRootParser(fhicl::ParameterSet const& pset);
1379  virtual ~AnaRootParser();
1380 
1381  /// read access to event
1382  void analyze(const art::Event& evt);
1383  // void beginJob() {}
1384  void beginSubRun(const art::SubRun& sr);
1385  void endSubRun(const art::SubRun& sr);
1386 
1387  private:
1388 
1389  void HitsBackTrack(detinfo::DetectorClocksData const& clockData, art::Ptr<recob::Hit> const& hit, int & trackid, float & maxe, float & purity );
1390  double length(const recob::Track& track);
1391  double driftedLength(detinfo::DetectorPropertiesData const& detProp,
1392  const simb::MCParticle& part, TLorentzVector& start, TLorentzVector& end, unsigned int &starti, unsigned int &endi);
1393  double driftedLength(detinfo::DetectorPropertiesData const& detProp,
1394  const sim::MCTrack& mctrack, TLorentzVector& tpcstart, TLorentzVector& tpcend, TLorentzVector& tpcmom);
1395  double length(const simb::MCParticle& part, TLorentzVector& start, TLorentzVector& end, unsigned int &starti, unsigned int &endi);
1396  double bdist(const TVector3& pos);
1397  int CountHits(const art::Event& evt, const art::InputTag& which, unsigned int cryostat, unsigned int tpc, unsigned int plane);
1398 
1399  TTree* fTree;
1400  // TTree* fPOT;
1401  // event information is huge and dynamic;
1402  // run information is much smaller and we still store it statically
1403  // in the event
1404  std::unique_ptr<AnaRootParserDataStruct> fData;
1405  // AnaRootParserDataStruct::RunData_t RunData;
1407 
1410 
1427  std::vector<std::string> fTrackModuleLabel;
1429  std::vector<std::string> fVertexModuleLabel;
1430  std::vector<std::string> fShowerModuleLabel;
1431  std::vector<std::string> fCalorimetryModuleLabel;
1432  std::vector<std::string> fParticleIDModuleLabel;
1433  std::vector<std::string> fMVAPIDShowerModuleLabel;
1434  std::vector<std::string> fMVAPIDTrackModuleLabel;
1435  std::vector<std::string> fFlashT0FinderLabel;
1436  std::vector<std::string> fMCT0FinderLabel;
1439  bool fIsMC; ///< whether to use a permanent buffer (faster, huge memory)
1440  bool fUseBuffer; ///< whether to use a permanent buffer (faster, huge memory)
1441 
1442 // bool fSaveRecobWireInfo; //whether to extract and save recob::wire info
1443  bool fSaveAuxDetInfo; ///< whether to extract and save auxiliary detector data
1444  bool fSaveCryInfo; ///whether to extract and save CRY particle data
1445  bool fSaveGenieInfo; ///whether to extract and save Genie information
1446  bool fSaveProtoInfo; ///whether to extract and save ProtDUNE beam simulation information
1447  bool fSavePhotonInfo; ///whether to extract and save collected photons
1448  bool fSaveGeneratorInfo; ///whether to extract and save Geant information
1449  bool fSaveGeantInfo; ///whether to extract and save Geant information
1450  bool fSaveGeantInAVInfo; ///whether to extract and save Geant information
1451  bool fSaveGeantTrajectoryInfo; ///whether to extract and save Geant information
1452  bool fSaveSimEnergyDepositTPCActiveInfo; ///whether to extract and save Cluster information
1453  bool fSaveMCShowerInfo; ///whether to extract and save MC Shower information
1454  bool fSaveMCTrackInfo; ///whether to extract and save MC Track information
1455  bool fSaveHitInfo; ///whether to extract and save Hit information
1456  bool fSaveRawDigitInfo; ///whether to extract and save raw digit information
1457  bool fSaveRecobWireInfo; ///whether to extract and save recob wire information
1458  bool fSaveTrackInfo; ///whether to extract and save Track information
1459  bool fSaveVertexInfo; ///whether to extract and save Vertex information
1460  bool fSaveClusterInfo; ///whether to extract and save Cluster information
1461  bool fSavePandoraNuVertexInfo; ///whether to extract and save nu vertex information from Pandora
1462  bool fSaveFlashInfo; ///whether to extract and save Flash information
1463  bool fSaveExternCounterInfo; ///whether to extract and save External Counter information
1464  bool fSaveShowerInfo; ///whether to extract and save Shower information
1465  bool fSavePFParticleInfo; ///whether to extract and save PFParticle information
1466 
1467  std::vector<std::string> fCosmicTaggerAssocLabel;
1468  std::vector<std::string> fContainmentTaggerAssocLabel;
1469  std::vector<std::string> fFlashMatchAssocLabel;
1470 
1471  bool bIgnoreMissingShowers; ///< whether to ignore missing shower information
1472 
1473  bool isCosmics; ///< if it contains cosmics
1474  bool fSaveCaloCosmics; ///< save calorimetry information for cosmics
1475  float fG4minE; ///< Energy threshold to save g4 particle info
1476 
1477  trkf::TrajectoryMCSFitter fMCSFitter; /// objet holding the configuration of the uBoone MCS fitting alg
1478 
1479  double ActiveBounds[6]; // Cryostat boundaries ( neg x, pos x, neg y, pos y, neg z, pos z )
1480 
1481  /// Returns the number of trackers configured
1482  size_t GetNTrackers() const { return fTrackModuleLabel.size(); }
1483 
1484  size_t GetNVertexAlgos() const { return fVertexModuleLabel.size(); }
1485 
1486  /// Returns the number of shower algorithms configured
1487  size_t GetNShowerAlgos() const { return fShowerModuleLabel.size(); }
1488 
1489  /// Returns the name of configured shower algorithms (converted to string)
1490  std::vector<std::string> GetShowerAlgos() const
1491  { return { fShowerModuleLabel.begin(), fShowerModuleLabel.end() }; }
1492 
1493  /// Creates the structure for the tree data; optionally initializes it
1494  void CreateData(bool bClearData = false)
1495  {
1496  if (!fData) {
1497  fData.reset
1498  (new AnaRootParserDataStruct(GetNTrackers(), GetNVertexAlgos(), GetShowerAlgos()));
1499  fData->SetBits(AnaRootParserDataStruct::tdCry, !fSaveCryInfo);
1500  fData->SetBits(AnaRootParserDataStruct::tdGenie, !fSaveGenieInfo);
1501  fData->SetBits(AnaRootParserDataStruct::tdProto, !fSaveProtoInfo);
1502  fData->SetBits(AnaRootParserDataStruct::tdPhotons, !fSavePhotonInfo);
1503  fData->SetBits(AnaRootParserDataStruct::tdGenerator, !fSaveGeneratorInfo);
1504  fData->SetBits(AnaRootParserDataStruct::tdGeant, !fSaveGeantInfo);
1505  fData->SetBits(AnaRootParserDataStruct::tdGeantInAV, !fSaveGeantInAVInfo);
1506  fData->SetBits(AnaRootParserDataStruct::tdGeantTrajectory, !fSaveGeantTrajectoryInfo);
1507  fData->SetBits(AnaRootParserDataStruct::tdSimEnergyDepositTPCActive, !fSaveSimEnergyDepositTPCActiveInfo);
1508  fData->SetBits(AnaRootParserDataStruct::tdMCshwr, !fSaveMCShowerInfo);
1509  fData->SetBits(AnaRootParserDataStruct::tdMCtrk, !fSaveMCTrackInfo);
1510  fData->SetBits(AnaRootParserDataStruct::tdHit, !fSaveHitInfo);
1511  fData->SetBits(AnaRootParserDataStruct::tdRawDigit, !fSaveRawDigitInfo);
1512  fData->SetBits(AnaRootParserDataStruct::tdRecobWire, !fSaveRecobWireInfo);
1513  fData->SetBits(AnaRootParserDataStruct::tdFlash, !fSaveFlashInfo);
1514  fData->SetBits(AnaRootParserDataStruct::tdCount, !fSaveExternCounterInfo);
1515  fData->SetBits(AnaRootParserDataStruct::tdShower, !fSaveShowerInfo);
1516  fData->SetBits(AnaRootParserDataStruct::tdCluster,!fSaveClusterInfo);
1517  fData->SetBits(AnaRootParserDataStruct::tdPandoraNuVertex,!fSavePandoraNuVertexInfo);
1518  fData->SetBits(AnaRootParserDataStruct::tdTrack, !fSaveTrackInfo);
1519  fData->SetBits(AnaRootParserDataStruct::tdVertex, !fSaveVertexInfo);
1520  fData->SetBits(AnaRootParserDataStruct::tdAuxDet, !fSaveAuxDetInfo);
1521  fData->SetBits(AnaRootParserDataStruct::tdPFParticle, !fSavePFParticleInfo);
1522  }
1523  else {
1524  fData->SetTrackers(GetNTrackers());
1525  fData->SetVertexAlgos(GetNVertexAlgos());
1526  fData->SetShowerAlgos(GetShowerAlgos());
1527  if (bClearData) fData->Clear();
1528  }
1529  } // CreateData()
1530 
1531  /// Sets the addresses of all the tree branches, creating the missing ones
1533  {
1534  CheckData(__func__); CheckTree(__func__);
1535  fData->SetAddresses
1536  (fTree, fTrackModuleLabel, fVertexModuleLabel, fShowerModuleLabel, isCosmics);
1537  } // SetAddresses()
1538 
1539  /// Sets the addresses of all the tree branches of the specified tracking algo,
1540  /// creating the missing ones
1541  void SetTrackerAddresses(size_t iTracker)
1542  {
1543  CheckData(__func__); CheckTree(__func__);
1544  if (iTracker >= fData->GetNTrackers()) {
1546  << "AnaRootParser::SetTrackerAddresses(): no tracker #" << iTracker
1547  << " (" << fData->GetNTrackers() << " available)";
1548  }
1549  fData->GetTrackerData(iTracker)
1550  .SetAddresses(fTree, fTrackModuleLabel[iTracker], isCosmics);
1551  } // SetTrackerAddresses()
1552 
1553 
1554  void SetVertexAddresses(size_t iVertexAlg)
1555  {
1556  CheckData(__func__); CheckTree(__func__);
1557  if (iVertexAlg >= fData->GetNVertexAlgos()) {
1559  << "AnaRootParser::SetVertexAddresses(): no vertex alg #" << iVertexAlg
1560  << " (" << fData->GetNVertexAlgos() << " available)";
1561  }
1562  fData->GetVertexData(iVertexAlg)
1563  .SetAddresses(fTree, fVertexModuleLabel[iVertexAlg], isCosmics);
1564  } // SetVertexAddresses()
1565 
1566  /// Sets the addresses of all the tree branches of the specified shower algo,
1567  /// creating the missing ones
1568  void SetShowerAddresses(size_t iShower)
1569  {
1570  CheckData(__func__); CheckTree(__func__);
1571  if (iShower >= fData->GetNShowerAlgos()) {
1573  << "AnaRootParser::SetShowerAddresses(): no shower algo #" << iShower
1574  << " (" << fData->GetNShowerAlgos() << " available)";
1575  }
1576  fData->GetShowerData(iShower).SetAddresses(fTree);
1577  } // SetShowerAddresses()
1578 
1579  /// Sets the addresses of the tree branch of the PFParticle,
1580  /// creating it if missing
1582  {
1583  CheckData(__func__); CheckTree(__func__);
1584  fData->GetPFParticleData().SetAddresses(fTree);
1585  } // SetPFParticleAddress()
1586 
1587  /// Create the output tree and the data structures, if needed
1588  void CreateTree(bool bClearData = false);
1589 
1590  /// Destroy the local buffers (existing branches will point to invalid address!)
1591  void DestroyData() { fData.reset(); }
1592 
1593  /// Helper function: throws if no data structure is available
1594  void CheckData(std::string caller) const
1595  {
1596  if (fData) return;
1598  << "AnaRootParser::" << caller << ": no data";
1599  } // CheckData()
1600  /// Helper function: throws if no tree is available
1601  void CheckTree(std::string caller) const
1602  {
1603  if (fTree) return;
1605  << "AnaRootParser::" << caller << ": no tree";
1606  } // CheckData()
1607 
1608  /// Stores the information of shower in slot iShower of showerData
1609  void FillShower(
1611  size_t iShower, recob::Shower const& showers, const bool fSavePFParticleInfo,
1612  const std::map<Short_t, Short_t> &showerIDtoPFParticleIDMap
1613  ) const;
1614 
1615  /// Stores the information of all showers into showerData
1616  void FillShowers(
1618  std::vector<recob::Shower> const& showers, const bool fSavePFParticleInfo,
1619  const std::map<Short_t, Short_t> &showerIDtoPFParticleIDMap
1620  ) const;
1621 
1622  }; // class dune::AnaRootParser
1623 } // namespace dune
1624 
1625 
1626 namespace { // local namespace
1627  /// Simple stringstream which empties its buffer on operator() call
1628  class AutoResettingStringSteam: public std::ostringstream {
1629  public:
1630  AutoResettingStringSteam& operator() () { str(""); return *this; }
1631  }; // class AutoResettingStringSteam
1632 
1633  /// Fills a sequence of TYPE elements
1634  template <typename ITER, typename TYPE>
1635  inline void FillWith(ITER from, ITER to, TYPE value)
1636  { std::fill(from, to, value); }
1637 
1638  /// Fills a sequence of TYPE elements
1639  template <typename ITER, typename TYPE>
1640  inline void FillWith(ITER from, size_t n, TYPE value)
1641  { std::fill(from, from + n, value); }
1642 
1643  /// Fills a container with begin()/end() interface
1644  template <typename CONT, typename V>
1645  inline void FillWith(CONT& data, const V& value)
1646  { FillWith(std::begin(data), std::end(data), value); }
1647 
1648 } // local namespace
1649 
1650 
1651 //------------------------------------------------------------------------------
1652 //--- AnaRootParserDataStruct::TrackDataStruct
1653 //---
1654 
1656 {
1657  MaxTracks = nTracks;
1658 
1659  trkId.resize(MaxTracks);
1660  NHitsPerTrack.resize(MaxTracks);
1661  trkncosmictags_tagger.resize(MaxTracks);
1662  trkcosmicscore_tagger.resize(MaxTracks);
1663  trkcosmictype_tagger.resize(MaxTracks);
1664  trkncosmictags_containmenttagger.resize(MaxTracks);
1665  trkcosmicscore_containmenttagger.resize(MaxTracks);
1666  trkcosmictype_containmenttagger.resize(MaxTracks);
1667  trkncosmictags_flashmatch.resize(MaxTracks);
1668  trkcosmicscore_flashmatch.resize(MaxTracks);
1669  trkcosmictype_flashmatch.resize(MaxTracks);
1670  trkstartx.resize(MaxTracks);
1671  trkstarty.resize(MaxTracks);
1672  trkstartz.resize(MaxTracks);
1673  trkstartd.resize(MaxTracks);
1674  trkendx.resize(MaxTracks);
1675  trkendy.resize(MaxTracks);
1676  trkendz.resize(MaxTracks);
1677  trkendd.resize(MaxTracks);
1678  trkflashT0.resize(MaxTracks);
1679  trktrueT0.resize(MaxTracks);
1680  trkstarttheta.resize(MaxTracks);
1681  trkstartphi.resize(MaxTracks);
1682  trkendtheta.resize(MaxTracks);
1683  trkendphi.resize(MaxTracks);
1684  trkstartdirectionx.resize(MaxTracks);
1685  trkstartdirectiony.resize(MaxTracks);
1686  trkstartdirectionz.resize(MaxTracks);
1687  trkenddirectionx.resize(MaxTracks);
1688  trkenddirectiony.resize(MaxTracks);
1689  trkenddirectionz.resize(MaxTracks);
1690  trkthetaxz.resize(MaxTracks);
1691  trkthetayz.resize(MaxTracks);
1692  trkmom.resize(MaxTracks);
1693  trkmomrange.resize(MaxTracks);
1694  trkmommschi2.resize(MaxTracks);
1695  trkmommsllhd.resize(MaxTracks);
1696  trkmommscmic.resize(MaxTracks);
1697  trkmommscfwd.resize(MaxTracks);
1698  trkmommscbwd.resize(MaxTracks);
1699  trkmommscllfwd.resize(MaxTracks);
1700  trkmommscllbwd.resize(MaxTracks);
1701  trkchi2PerNDF.resize(MaxTracks);
1702  trkNDF.resize(MaxTracks);
1703  trklen.resize(MaxTracks);
1704  trklenstraightline.resize(MaxTracks);
1705  trksvtxid.resize(MaxTracks);
1706  trkevtxid.resize(MaxTracks);
1707  // PID variables
1708  trkpidpdg.resize(MaxTracks);
1709  trkpidchi.resize(MaxTracks);
1710  trkpidchipr.resize(MaxTracks);
1711  trkpidchika.resize(MaxTracks);
1712  trkpidchipi.resize(MaxTracks);
1713  trkpidchimu.resize(MaxTracks);
1714  trkpidpida.resize(MaxTracks);
1715  trkpidbestplane.resize(MaxTracks);
1716  trkpidmvamu.resize(MaxTracks);
1717  trkpidmvae.resize(MaxTracks);
1718  trkpidmvapich.resize(MaxTracks);
1719  trkpidmvaphoton.resize(MaxTracks);
1720  trkpidmvapr.resize(MaxTracks);
1721 
1722  trkke.resize(MaxTracks);
1723  trkrange.resize(MaxTracks);
1724  trkidtruth.resize(MaxTracks);
1725  trkorigin.resize(MaxTracks);
1726  trkpdgtruth.resize(MaxTracks);
1727  trkefftruth.resize(MaxTracks);
1728  trkpurtruth.resize(MaxTracks);
1729  trkpurity.resize(MaxTracks);
1730  trkcompleteness.resize(MaxTracks);
1731  trkg4id.resize(MaxTracks);
1732  trkorig.resize(MaxTracks);
1733  trkpitchc.resize(MaxTracks);
1734  ntrkhitsperview.resize(MaxTracks);
1735 
1736  trkdedx.resize(MaxTracks);
1737  trkdqdx.resize(MaxTracks);
1738  trkresrg.resize(MaxTracks);
1739  trktpc.resize(MaxTracks);
1740  trkxyz.resize(MaxTracks);
1741 
1742  trkhasPFParticle.resize(MaxTracks);
1743  trkPFParticleID.resize(MaxTracks);
1744 
1745 } // dune::AnaRootParserDataStruct::TrackDataStruct::Resize()
1746 
1748  Resize(MaxTracks);
1749  ntracks = 0;
1750 
1751  std::fill(trkdedx2, trkdedx2 + sizeof(trkdedx2)/sizeof(trkdedx2[0]), -999.);
1752  std::fill(trkdqdx2, trkdqdx2 + sizeof(trkdqdx2)/sizeof(trkdqdx2[0]), -999.);
1753  std::fill(trktpc2, trktpc2 + sizeof(trktpc2)/sizeof(trktpc2[0]), -999.);
1754  std::fill(trkx2, trkx2 + sizeof(trkx2)/sizeof(trkx2[0]), -999.);
1755  std::fill(trky2, trky2 + sizeof(trky2)/sizeof(trky2[0]), -999.);
1756  std::fill(trkz2, trkz2 + sizeof(trkz2)/sizeof(trkz2[0]), -999.);
1757 
1758  std::fill(hittrkx, hittrkx + sizeof(hittrkx)/sizeof(hittrkx[0]), -999.);
1759  std::fill(hittrky, hittrky + sizeof(hittrky)/sizeof(hittrky[0]), -999.);
1760  std::fill(hittrkz, hittrkz + sizeof(hittrkz)/sizeof(hittrkz[0]), -999.);
1761 
1762  std::fill(hittrklocaltrackdirectionx, hittrklocaltrackdirectionx + sizeof(hittrklocaltrackdirectionx)/sizeof(hittrklocaltrackdirectionx[0]), -999.);
1763  std::fill(hittrklocaltrackdirectiony, hittrklocaltrackdirectiony + sizeof(hittrklocaltrackdirectiony)/sizeof(hittrklocaltrackdirectiony[0]), -999.);
1764  std::fill(hittrklocaltrackdirectionz, hittrklocaltrackdirectionz + sizeof(hittrklocaltrackdirectionz)/sizeof(hittrklocaltrackdirectionz[0]), -999.);
1765  std::fill(hittrklocaltrackdirectiontheta, hittrklocaltrackdirectiontheta + sizeof(hittrklocaltrackdirectiontheta)/sizeof(hittrklocaltrackdirectiontheta[0]), -999.);
1766  std::fill(hittrklocaltrackdirectionphi, hittrklocaltrackdirectionphi + sizeof(hittrklocaltrackdirectionphi)/sizeof(hittrklocaltrackdirectionphi[0]), -999.);
1767 
1768 
1769  std::fill(hittrkpitchC, hittrkpitchC + sizeof(hittrkpitchC)/sizeof(hittrkpitchC[0]), -999.);
1770 
1771  std::fill(hittrkds, hittrkds + sizeof(hittrkds)/sizeof(hittrkds[0]), -999.);
1772 
1773  std::fill(hittrkchannel, hittrkchannel + sizeof(hittrkchannel)/sizeof(hittrkchannel[0]), -999);
1774  std::fill(hittrktpc, hittrktpc + sizeof(hittrktpc)/sizeof(hittrktpc[0]), -999);
1775  std::fill(hittrkview, hittrkview + sizeof(hittrkview)/sizeof(hittrkview[0]), -999);
1776  std::fill(hittrkwire, hittrkwire + sizeof(hittrkwire)/sizeof(hittrkwire[0]), -999);
1777  std::fill(hittrkpeakT, hittrkpeakT + sizeof(hittrkpeakT)/sizeof(hittrkpeakT[0]), -999.);
1778  std::fill(hittrkchargeintegral, hittrkchargeintegral + sizeof(hittrkchargeintegral)/sizeof(hittrkchargeintegral[0]), -999.);
1779  std::fill(hittrkph, hittrkph + sizeof(hittrkph)/sizeof(hittrkph[0]), -999.);
1780  std::fill(hittrkchargesum, hittrkchargesum + sizeof(hittrkchargesum)/sizeof(hittrkchargesum[0]), -999.);
1781  std::fill(hittrkstarT, hittrkstarT + sizeof(hittrkstarT)/sizeof(hittrkstarT[0]), -999.);
1782  std::fill(hittrkendT, hittrkendT + sizeof(hittrkendT)/sizeof(hittrkendT[0]), -999.);
1783  std::fill(hittrkrms, hittrkrms + sizeof(hittrkrms)/sizeof(hittrkrms[0]), -999.);
1784  std::fill(hittrkgoddnessofFit, hittrkgoddnessofFit + sizeof(hittrkgoddnessofFit)/sizeof(hittrkgoddnessofFit[0]), -999.);
1785  std::fill(hittrkmultiplicity, hittrkmultiplicity + sizeof(hittrkmultiplicity)/sizeof(hittrkmultiplicity[0]), -999);
1786  std::fill(hittrktrueID, hittrktrueID + sizeof(hittrktrueID)/sizeof(hittrktrueID[0]), -999);
1787  std::fill(hittrktrueEnergyMax, hittrktrueEnergyMax + sizeof(hittrktrueEnergyMax)/sizeof(hittrktrueEnergyMax[0]), -999);
1788  std::fill(hittrktrueEnergyFraction, hittrktrueEnergyFraction + sizeof(hittrktrueEnergyFraction)/sizeof(hittrktrueEnergyFraction[0]), -999);
1789 
1790  FillWith(trkId , -999 );
1791  FillWith(NHitsPerTrack , -999 );
1792  FillWith(trkncosmictags_tagger, -999 );
1793  FillWith(trkcosmicscore_tagger, -999.);
1794  FillWith(trkcosmictype_tagger, -999 );
1795  FillWith(trkncosmictags_containmenttagger, -999 );
1796  FillWith(trkcosmicscore_containmenttagger, -999.);
1797  FillWith(trkcosmictype_containmenttagger, -999 );
1798  FillWith(trkncosmictags_flashmatch, -999 );
1799  FillWith(trkcosmicscore_flashmatch, -999.);
1800  FillWith(trkcosmictype_flashmatch, -999 );
1801  FillWith(trkstartx , -999.);
1802  FillWith(trkstarty , -999.);
1803  FillWith(trkstartz , -999.);
1804  FillWith(trkstartd , -999.);
1805  FillWith(trkendx , -999.);
1806  FillWith(trkendy , -999.);
1807  FillWith(trkendz , -999.);
1808  FillWith(trkendd , -999.);
1809  FillWith(trkflashT0 , -999.);
1810  FillWith(trktrueT0 , -999.);
1811  FillWith(trkg4id , -9999 );
1812  FillWith(trkpurity , -999.);
1813  FillWith(trkcompleteness, -999.);
1814  FillWith(trkorig , -9999 );
1815  FillWith(trkstarttheta , -999.);
1816  FillWith(trkstartphi , -999.);
1817  FillWith(trkendtheta , -999.);
1818  FillWith(trkendphi , -999.);
1819  FillWith(trkstartdirectionx, -999.);
1820  FillWith(trkstartdirectiony, -999.);
1821  FillWith(trkstartdirectionz, -999.);
1822  FillWith(trkenddirectionx , -999.);
1823  FillWith(trkenddirectiony , -999.);
1824  FillWith(trkenddirectionz , -999.);
1825  FillWith(trkthetaxz , -999.);
1826  FillWith(trkthetayz , -999.);
1827  FillWith(trkmom , -999.);
1828  FillWith(trkmomrange , -999.);
1829  FillWith(trkmommschi2 , -999.);
1830  FillWith(trkmommsllhd , -999.);
1831  FillWith(trkmommscmic , -999.);
1832  FillWith(trkmommscfwd , -999.);
1833  FillWith(trkmommscbwd , -999.);
1834  FillWith(trkmommscllfwd , -999.);
1835  FillWith(trkmommscllbwd , -999.);
1836  FillWith(trkchi2PerNDF, -999.);
1837  FillWith(trkNDF, -999.);
1838  FillWith(trklen , -999.);
1839  FillWith(trklenstraightline, -999.);
1840  FillWith(trksvtxid , -1);
1841  FillWith(trkevtxid , -1);
1842  FillWith(trkpidbestplane, -1);
1843  FillWith(trkpidmvamu , -999.);
1844  FillWith(trkpidmvae , -999.);
1845  FillWith(trkpidmvapich, -999.);
1846  FillWith(trkpidmvaphoton , -999.);
1847  FillWith(trkpidmvapr , -999.);
1848 
1849  FillWith(trkhasPFParticle, -1);
1850  FillWith(trkPFParticleID , -1);
1851 
1852  for (size_t iTrk = 0; iTrk < MaxTracks; ++iTrk){
1853 
1854  // the following are BoxedArray's;
1855  // their iterators traverse all the array dimensions
1856  FillWith(trkke[iTrk] , -999.);
1857  FillWith(trkrange[iTrk] , -999.);
1858  FillWith(trkidtruth[iTrk] , -9999 );
1859  FillWith(trkorigin[iTrk] , -1 );
1860  FillWith(trkpdgtruth[iTrk], -9999 );
1861  FillWith(trkefftruth[iTrk], -999.);
1862  FillWith(trkpurtruth[iTrk], -999.);
1863  FillWith(trkpitchc[iTrk] , -999.);
1864  FillWith(ntrkhitsperview[iTrk] , -999 );
1865 
1866  FillWith(trkdedx[iTrk], 0.);
1867  FillWith(trkdqdx[iTrk], 0.);
1868  FillWith(trkresrg[iTrk], 0.);
1869  FillWith(trktpc[iTrk], -1);
1870  FillWith(trkxyz[iTrk], 0.);
1871 
1872  FillWith(trkpidpdg[iTrk] , -1);
1873  FillWith(trkpidchi[iTrk] , -999.);
1874  FillWith(trkpidchipr[iTrk] , -999.);
1875  FillWith(trkpidchika[iTrk] , -999.);
1876  FillWith(trkpidchipi[iTrk] , -999.);
1877  FillWith(trkpidchimu[iTrk] , -999.);
1878  FillWith(trkpidpida[iTrk] , -999.);
1879  } // for track
1880 
1881 } // dune::AnaRootParserDataStruct::TrackDataStruct::Clear()
1882 
1883 
1885  TTree* pTree, std::string tracker, bool isCosmics
1886  ) {
1887  if (MaxTracks == 0) return; // no tracks, no tree!
1888 
1890 
1891  AutoResettingStringSteam sstr;
1892  sstr() << kMaxTrackHits;
1893  std::string MaxTrackHitsIndexStr("[" + sstr.str() + "]");
1894 
1895  std::string TrackLabel = tracker;
1896  std::string BranchName;
1897 
1898  BranchName = "NumberOfTracks";
1899  CreateBranch(BranchName, &ntracks, BranchName + "/S");
1900  std::string NTracksIndexStr = "[" + BranchName + "]";
1901 
1902  BranchName = "TrackID";
1903  CreateBranch(BranchName, trkId, BranchName + NTracksIndexStr + "/S");
1904 
1905  BranchName = "Track_NumberOfHits";
1906  CreateBranch(BranchName, NHitsPerTrack, BranchName + NTracksIndexStr + "/S");
1907 
1908  BranchName = "Track_Length_Trajectory";
1909  CreateBranch(BranchName, trklen, BranchName + NTracksIndexStr + "/F");
1910 
1911  BranchName = "Track_Length_StraightLine";
1912  CreateBranch(BranchName, trklenstraightline, BranchName + NTracksIndexStr + "/F");
1913 
1914  BranchName = "Track_Chi2PerNDF";
1915  CreateBranch(BranchName, trkchi2PerNDF, BranchName + NTracksIndexStr + "/F");
1916 
1917  BranchName = "Track_NDF";
1918  CreateBranch(BranchName, trkNDF, BranchName + NTracksIndexStr + "/F");
1919 
1920  BranchName = "Track_StartPoint_X";
1921  CreateBranch(BranchName, trkstartx, BranchName + NTracksIndexStr + "/F");
1922 
1923  BranchName = "Track_StartPoint_Y";
1924  CreateBranch(BranchName, trkstarty, BranchName + NTracksIndexStr + "/F");
1925 
1926  BranchName = "Track_StartPoint_Z";
1927  CreateBranch(BranchName, trkstartz, BranchName + NTracksIndexStr + "/F");
1928 
1929  BranchName = "Track_StartPoint_DistanceToBoundary";
1930  CreateBranch(BranchName, trkstartd, BranchName + NTracksIndexStr + "/F");
1931 
1932  BranchName = "Track_EndPoint_X";
1933  CreateBranch(BranchName, trkendx, BranchName + NTracksIndexStr + "/F");
1934 
1935  BranchName = "Track_EndPoint_Y";
1936  CreateBranch(BranchName, trkendy, BranchName + NTracksIndexStr + "/F");
1937 
1938  BranchName = "Track_EndPoint_Z";
1939  CreateBranch(BranchName, trkendz, BranchName + NTracksIndexStr + "/F");
1940 
1941  BranchName = "Track_EndPoint_DistanceToBoundary";
1942  CreateBranch(BranchName, trkendd, BranchName + NTracksIndexStr + "/F");
1943 
1944  BranchName = "Track_StartDirection_Theta";
1945  CreateBranch(BranchName, trkstarttheta, BranchName + NTracksIndexStr + "/F");
1946 
1947  BranchName = "Track_StartDirection_Phi";
1948  CreateBranch(BranchName, trkstartphi, BranchName + NTracksIndexStr + "/F");
1949 
1950  BranchName = "Track_StartDirection_X";
1951  CreateBranch(BranchName, trkstartdirectionx, BranchName + NTracksIndexStr + "/F");
1952 
1953  BranchName = "Track_StartDirection_Y";
1954  CreateBranch(BranchName, trkstartdirectiony, BranchName + NTracksIndexStr + "/F");
1955 
1956  BranchName = "Track_StartDirection_Z";
1957  CreateBranch(BranchName, trkstartdirectionz, BranchName + NTracksIndexStr + "/F");
1958 
1959  BranchName = "Track_EndDirection_Theta";
1960  CreateBranch(BranchName, trkendtheta, BranchName + NTracksIndexStr + "/F");
1961 
1962  BranchName = "Track_EndDirection_Phi";
1963  CreateBranch(BranchName, trkendphi, BranchName + NTracksIndexStr + "/F");
1964 
1965  BranchName = "Track_EndDirection_X";
1966  CreateBranch(BranchName, trkenddirectionx, BranchName + NTracksIndexStr + "/F");
1967 
1968  BranchName = "Track_EndDirection_Y";
1969  CreateBranch(BranchName, trkenddirectiony, BranchName + NTracksIndexStr + "/F");
1970 
1971  BranchName = "Track_EndDirection_Z";
1972  CreateBranch(BranchName, trkenddirectionz, BranchName + NTracksIndexStr + "/F");
1973 
1974 
1975 
1976  //Branches for calculated momentum
1977  BranchName = "Track_Momentum";
1978  CreateBranch(BranchName, trkmom, BranchName + NTracksIndexStr + "/F");
1979 
1980  BranchName = "Track_Momentum_Range";
1981  CreateBranch(BranchName, trkmomrange, BranchName + NTracksIndexStr + "/F");
1982 
1983  BranchName = "Track_Momentum_mschi";
1984  CreateBranch(BranchName, trkmommschi2, BranchName + NTracksIndexStr + "/F");
1985 
1986  BranchName = "Track_Momentum_mscmic";
1987  CreateBranch(BranchName, trkmommscmic, BranchName + NTracksIndexStr + "/F");
1988 
1989  BranchName = "Track_Momentum_mscfwd";
1990  CreateBranch(BranchName, trkmommscfwd, BranchName + NTracksIndexStr + "/F");
1991 
1992  BranchName = "Track_Momentum_mscbwd";
1993  CreateBranch(BranchName, trkmommscbwd, BranchName + NTracksIndexStr + "/F");
1994 
1995  BranchName = "Track_Momentum_mscllfwd";
1996  CreateBranch(BranchName, trkmommscllfwd, BranchName + NTracksIndexStr + "/F");
1997 
1998  BranchName = "Track_Momentum_mscllbwd";
1999  CreateBranch(BranchName, trkmommscllbwd, BranchName + NTracksIndexStr + "/F");
2000 
2001 
2002  /*
2003  BranchName = "trkncosmictags_tagger";
2004  CreateBranch(BranchName, trkncosmictags_tagger, BranchName + NTracksIndexStr + "/S");
2005 
2006  BranchName = "trkcosmicscore_tagger";
2007  CreateBranch(BranchName, trkcosmicscore_tagger, BranchName + NTracksIndexStr + "/F");
2008 
2009  BranchName = "trkcosmictype_tagger";
2010  CreateBranch(BranchName, trkcosmictype_tagger, BranchName + NTracksIndexStr + "/S");
2011 
2012  BranchName = "trkncosmictags_containmenttagger";
2013  CreateBranch(BranchName, trkncosmictags_containmenttagger, BranchName + NTracksIndexStr + "/S");
2014 
2015  BranchName = "trkcosmicscore_containmenttagger";
2016  CreateBranch(BranchName, trkcosmicscore_containmenttagger, BranchName + NTracksIndexStr + "/F");
2017 
2018  BranchName = "trkcosmictype_containmenttagger";
2019  CreateBranch(BranchName, trkcosmictype_containmenttagger, BranchName + NTracksIndexStr + "/S");
2020 
2021  BranchName = "trkncosmictags_flashmatch";
2022  CreateBranch(BranchName, trkncosmictags_flashmatch, BranchName + NTracksIndexStr + "/S");
2023 
2024  BranchName = "trkcosmicscore_flashmatch";
2025  CreateBranch(BranchName, trkcosmicscore_flashmatch, BranchName + NTracksIndexStr + "/F");
2026 
2027  BranchName = "trkcosmictype_flashmatch";
2028  CreateBranch(BranchName, trkcosmictype_flashmatch, BranchName + NTracksIndexStr + "/S");
2029  */
2030  /*
2031  BranchName = "Track_KineticEnergy";
2032  CreateBranch(BranchName, trkke, BranchName + NTracksIndexStr + "[2]/F");
2033 
2034  BranchName = "Track_Range";
2035  CreateBranch(BranchName, trkrange, BranchName + NTracksIndexStr + "[2]/F");
2036  */
2037  /*
2038  BranchName = "trkidtruth";
2039  CreateBranch(BranchName, trkidtruth, BranchName + NTracksIndexStr + "[2]/I");
2040 
2041  BranchName = "trkorigin";
2042  CreateBranch(BranchName, trkorigin, BranchName + NTracksIndexStr + "[2]/S");
2043 
2044  BranchName = "trkpdgtruth";
2045  CreateBranch(BranchName, trkpdgtruth, BranchName + NTracksIndexStr + "[2]/I");
2046 
2047  BranchName = "trkefftruth";
2048  CreateBranch(BranchName, trkefftruth, BranchName + NTracksIndexStr + "[2]/F");
2049 
2050  BranchName = "trkpurtruth";
2051  CreateBranch(BranchName, trkpurtruth, BranchName + NTracksIndexStr + "[2]/F");
2052  */
2053  BranchName = "Track_PitchInViews";
2054  CreateBranch(BranchName, trkpitchc, BranchName + NTracksIndexStr + "[2]/F");
2055 
2056  BranchName = "Track_NumberOfHitsPerView";
2057  CreateBranch(BranchName, ntrkhitsperview, BranchName + NTracksIndexStr + "[2]/S");
2058 
2059 
2060  /*
2061  BranchName = "trkresrg";
2062  CreateBranch(BranchName, trkresrg, BranchName + "[no_hits]/F");
2063  */
2064 /*
2065  BranchName = "Track_TPC";
2066  CreateBranch(BranchName, trktpc2, BranchName + "[no_hits]/F");
2067 
2068  BranchName = "Track_dEdx";
2069  CreateBranch(BranchName, trkdedx2, BranchName + "[no_hits]/F");
2070 
2071  BranchName = "Track_dQdx";
2072  CreateBranch(BranchName, trkdqdx2, BranchName + "[no_hits]/F");
2073 
2074  BranchName = "Track_HitX";
2075  CreateBranch(BranchName, trkx2, BranchName + "[no_hits]/F");
2076 
2077  BranchName = "Track_HitY";
2078  CreateBranch(BranchName, trky2, BranchName + "[no_hits]/F");
2079 
2080  BranchName = "Track_HitZ";
2081  CreateBranch(BranchName, trkz2, BranchName + "[no_hits]/F");
2082 */
2083 //////////// new arrays ///////////////////////////
2084 
2085  BranchName = "Track_Hit_X";
2086  CreateBranch(BranchName, hittrkx, BranchName + "[no_hits]/F");
2087 
2088  BranchName = "Track_Hit_Y";
2089  CreateBranch(BranchName, hittrky, BranchName + "[no_hits]/F");
2090 
2091  BranchName = "Track_Hit_Z";
2092  CreateBranch(BranchName, hittrkz, BranchName + "[no_hits]/F");
2093 
2094  BranchName = "Track_Hit_LocalTrackDirection_X";
2095  CreateBranch(BranchName, hittrklocaltrackdirectionx, BranchName + "[no_hits]/F");
2096 
2097  BranchName = "Track_Hit_LocalTrackDirection_Y";
2098  CreateBranch(BranchName, hittrklocaltrackdirectiony, BranchName + "[no_hits]/F");
2099 
2100  BranchName = "Track_Hit_LocalTrackDirection_Z";
2101  CreateBranch(BranchName, hittrklocaltrackdirectionz, BranchName + "[no_hits]/F");
2102 
2103  BranchName = "Track_Hit_LocalTrackDirection_Theta";
2104  CreateBranch(BranchName, hittrklocaltrackdirectiontheta, BranchName + "[no_hits]/F");
2105 
2106  BranchName = "Track_Hit_LocalTrackDirection_Phi";
2107  CreateBranch(BranchName, hittrklocaltrackdirectionphi, BranchName + "[no_hits]/F");
2108 
2109  BranchName = "Track_Hit_ds_LocalTrackDirection";
2110  CreateBranch(BranchName, hittrkpitchC, BranchName + "[no_hits]/F");
2111 
2112  BranchName = "Track_Hit_ds_3DPosition";
2113  CreateBranch(BranchName, hittrkds, BranchName + "[no_hits]/F");
2114 
2115  BranchName = "Track_Hit_TPC";
2116  CreateBranch(BranchName, hittrktpc, BranchName + "[no_hits]/S");
2117 
2118  BranchName = "Track_Hit_View";
2119  CreateBranch(BranchName, hittrkview, BranchName + "[no_hits]/S");
2120 
2121  BranchName = "Track_Hit_Channel";
2122  CreateBranch(BranchName, hittrkchannel, BranchName + "[no_hits]/S");
2123 
2124 // BranchName = "Track_Hit_Wire";
2125 // CreateBranch(BranchName, hittrkwire, BranchName + "[no_hits]/S");
2126 
2127  BranchName = "Track_Hit_PeakTime";
2128  CreateBranch(BranchName, hittrkpeakT, BranchName + "[no_hits]/F");
2129 
2130  BranchName = "Track_Hit_ChargeSummedADC";
2131  CreateBranch(BranchName, hittrkchargesum, BranchName + "[no_hits]/F");
2132 
2133  BranchName = "Track_Hit_ChargeIntegral";
2134  CreateBranch(BranchName, hittrkchargeintegral, BranchName + "[no_hits]/F");
2135 
2136  BranchName = "Track_Hit_Amplitude";
2137  CreateBranch(BranchName, hittrkph, BranchName + "[no_hits]/F");
2138 
2139  BranchName = "Track_Hit_StartTime";
2140  CreateBranch(BranchName, hittrkstarT, BranchName + "[no_hits]/F");
2141 
2142  BranchName = "Track_Hit_EndTime";
2143  CreateBranch(BranchName, hittrkendT, BranchName + "[no_hits]/F");
2144 
2145  BranchName = "Track_Hit_Width";
2146  CreateBranch(BranchName, hittrkrms, BranchName + "[no_hits]/F");
2147 
2148  BranchName = "Track_Hit_GoodnessOfFit";
2149  CreateBranch(BranchName, hittrkgoddnessofFit, BranchName + "[no_hits]/F");
2150 
2151  BranchName = "Track_Hit_Multiplicity";
2152  CreateBranch(BranchName, hittrkmultiplicity, BranchName + "[no_hits]/S");
2153 
2154  BranchName = "Track_Hit_trueID";
2155  CreateBranch(BranchName, hittrktrueID, BranchName + "[no_hits]/I");
2156 
2157  BranchName = "Track_Hit_trueEnergyMax";
2158  CreateBranch(BranchName, hittrktrueEnergyMax, BranchName + "[no_hits]/F");
2159 
2160  BranchName = "Track_Hit_trueEnergyFraction";
2161  CreateBranch(BranchName, hittrktrueEnergyFraction, BranchName + "[no_hits]/F");
2162 
2163 //////////// end new arrays ///////////////////////////
2164 
2165 
2166 
2167  /*
2168  if (!isCosmics){
2169  BranchName = "Track_dEdx";
2170  CreateBranch(BranchName, trkdedx, BranchName + NTracksIndexStr + "[2]" + MaxTrackHitsIndexStr + "/F");
2171 
2172  BranchName = "Track_dQdx";
2173  CreateBranch(BranchName, trkdqdx, BranchName + NTracksIndexStr + "[2]" + MaxTrackHitsIndexStr + "/F");
2174 
2175  BranchName = "trkresrg";
2176  CreateBranch(BranchName, trkresrg, BranchName + NTracksIndexStr + "[2]" + MaxTrackHitsIndexStr + "/F");
2177 
2178  BranchName = "Track_TPC";
2179  CreateBranch(BranchName, trktpc, BranchName + NTracksIndexStr + "[2]" + MaxTrackHitsIndexStr + "/I");
2180 
2181  BranchName = "Track_XYZ";
2182  CreateBranch(BranchName, trkxyz, BranchName + NTracksIndexStr + "[2]" + MaxTrackHitsIndexStr + "[3]" + "/F");
2183  }
2184  */
2185 
2186  /*
2187  BranchName = "trkflashT0";
2188  CreateBranch(BranchName, trkflashT0, BranchName + NTracksIndexStr + "/F");
2189 
2190  BranchName = "trktrueT0";
2191  CreateBranch(BranchName, trktrueT0, BranchName + NTracksIndexStr + "/F");
2192 
2193  BranchName = "trkg4id";
2194  CreateBranch(BranchName, trkg4id, BranchName + NTracksIndexStr + "/I");
2195 
2196  BranchName = "trkorig";
2197  CreateBranch(BranchName, trkorig, BranchName + NTracksIndexStr + "/I");
2198 
2199  BranchName = "trkpurity";
2200  CreateBranch(BranchName, trkpurity, BranchName + NTracksIndexStr + "/F");
2201 
2202  BranchName = "trkcompleteness";
2203  CreateBranch(BranchName, trkcompleteness, BranchName + NTracksIndexStr + "/F");
2204  */
2205 
2206  /*
2207 
2208 
2209  BranchName = "trkthetaxz";
2210  CreateBranch(BranchName, trkthetaxz, BranchName + NTracksIndexStr + "/F");
2211 
2212  BranchName = "trkthetayz";
2213  CreateBranch(BranchName, trkthetayz, BranchName + NTracksIndexStr + "/F");
2214 
2215  BranchName = "trkmom";
2216  CreateBranch(BranchName, trkmom, BranchName + NTracksIndexStr + "/F");
2217 
2218  BranchName = "trkmomrange";
2219  CreateBranch(BranchName, trkmomrange, BranchName + NTracksIndexStr + "/F");
2220  */
2221  /*
2222  BranchName = "trkmommschi2";
2223  CreateBranch(BranchName, trkmommschi2, BranchName + NTracksIndexStr + "/F");
2224 
2225  BranchName = "trkmommsllhd";
2226  CreateBranch(BranchName, trkmommsllhd, BranchName + NTracksIndexStr + "/F");
2227  */
2228 
2229  /*
2230  BranchName = "trksvtxid";
2231  CreateBranch(BranchName, trksvtxid, BranchName + NTracksIndexStr + "/S");
2232 
2233  BranchName = "trkevtxid";
2234  CreateBranch(BranchName, trkevtxid, BranchName + NTracksIndexStr + "/S");
2235 
2236  BranchName = "trkpidmvamu";
2237  CreateBranch(BranchName, trkpidmvamu, BranchName + NTracksIndexStr + "/F");
2238 
2239  BranchName = "trkpidmvae";
2240  CreateBranch(BranchName, trkpidmvae, BranchName + NTracksIndexStr + "/F");
2241 
2242  BranchName = "trkpidmvapich";
2243  CreateBranch(BranchName, trkpidmvapich, BranchName + NTracksIndexStr + "/F");
2244 
2245  BranchName = "trkpidmvaphoton";
2246  CreateBranch(BranchName, trkpidmvaphoton, BranchName + NTracksIndexStr + "/F");
2247 
2248  BranchName = "trkpidmvapr";
2249  CreateBranch(BranchName, trkpidmvapr, BranchName + NTracksIndexStr + "/F");
2250 
2251  BranchName = "trkpidpdg";
2252  CreateBranch(BranchName, trkpidpdg, BranchName + NTracksIndexStr + "[2]/I");
2253 
2254  BranchName = "trkpidchi";
2255  CreateBranch(BranchName, trkpidchi, BranchName + NTracksIndexStr + "[2]/F");
2256 
2257  BranchName = "trkpidchipr";
2258  CreateBranch(BranchName, trkpidchipr, BranchName + NTracksIndexStr + "[2]/F");
2259 
2260  BranchName = "trkpidchika";
2261  CreateBranch(BranchName, trkpidchika, BranchName + NTracksIndexStr + "[2]/F");
2262 
2263  BranchName = "trkpidchipi";
2264  CreateBranch(BranchName, trkpidchipi, BranchName + NTracksIndexStr + "[2]/F");
2265 
2266  BranchName = "trkpidchimu";
2267  CreateBranch(BranchName, trkpidchimu, BranchName + NTracksIndexStr + "[2]/F");
2268 
2269  BranchName = "trkpidpida";
2270  CreateBranch(BranchName, trkpidpida, BranchName + NTracksIndexStr + "[2]/F");
2271 
2272  BranchName = "trkpidbestview";
2273  CreateBranch(BranchName, trkpidbestplane, BranchName + NTracksIndexStr + "/S");
2274 
2275  BranchName = "trkhasPFParticle";
2276  CreateBranch(BranchName, trkhasPFParticle, BranchName + NTracksIndexStr + "/S");
2277 
2278  BranchName = "trkPFParticleID";
2279  CreateBranch(BranchName, trkPFParticleID, BranchName + NTracksIndexStr + "/S");
2280  */
2281 } // dune::AnaRootParserDataStruct::TrackDataStruct::SetAddresses()
2282 
2283 
2284 
2286 {
2287  MaxVertices = nVertices;
2288  vtxId.resize(MaxVertices);
2289  vtxx.resize(MaxVertices);
2290  vtxy.resize(MaxVertices);
2291  vtxz.resize(MaxVertices);
2292 
2293  vtxhasPFParticle.resize(MaxVertices);
2294  vtxPFParticleID.resize(MaxVertices);
2295 }
2296 
2298  Resize(MaxVertices);
2299  nvtx = -999;
2300 
2301  FillWith(vtxId , -999 );
2302  FillWith(vtxx , -999 );
2303  FillWith(vtxy , -999 );
2304  FillWith(vtxz , -999 );
2305  FillWith(vtxhasPFParticle, -1 );
2306  FillWith(vtxPFParticleID , -1 );
2307 }
2308 
2310  TTree* pTree, std::string alg, bool isCosmics
2311  ) {
2312  if (MaxVertices == 0) return; // no tracks, no tree!
2313 
2315 
2316  AutoResettingStringSteam sstr;
2317 
2318  std::string VertexLabel = alg;
2319  std::string BranchName;
2320  /*
2321  BranchName = "nvtx_" + VertexLabel;
2322  CreateBranch(BranchName, &nvtx, BranchName + "/S");
2323  std::string NVertexIndexStr = "[" + BranchName + "]";
2324 
2325  BranchName = "vtxId_" + VertexLabel;
2326  CreateBranch(BranchName, vtxId, BranchName + NVertexIndexStr + "/S");
2327 
2328  BranchName = "vtxx_" + VertexLabel;
2329  CreateBranch(BranchName, vtxx, BranchName + NVertexIndexStr + "/F");
2330 
2331  BranchName = "vtxy_" + VertexLabel;
2332  CreateBranch(BranchName, vtxy, BranchName + NVertexIndexStr + "/F");
2333 
2334  BranchName = "vtxz_" + VertexLabel;
2335  CreateBranch(BranchName, vtxz, BranchName + NVertexIndexStr + "/F");
2336 
2337  BranchName = "vtxhasPFParticle_" + VertexLabel;
2338  CreateBranch(BranchName, vtxhasPFParticle, BranchName + NVertexIndexStr + "/S");
2339 
2340  BranchName = "vtxPFParticleID_" + VertexLabel;
2341  CreateBranch(BranchName, vtxPFParticleID, BranchName + NVertexIndexStr + "/S");
2342  */
2343 }
2344 
2345 //------------------------------------------------------------------------------
2346 //--- AnaRootParserDataStruct::PFParticleDataStruct
2347 //---
2348 
2350 {
2351  MaxPFParticles = nPFParticles;
2352 
2353  pfp_selfID.resize(MaxPFParticles);
2354  pfp_isPrimary.resize(MaxPFParticles);
2355  pfp_numDaughters.resize(MaxPFParticles);
2356  pfp_daughterIDs.resize(MaxPFParticles);
2357  pfp_parentID.resize(MaxPFParticles);
2358  pfp_vertexID.resize(MaxPFParticles);
2359  pfp_isShower.resize(MaxPFParticles);
2360  pfp_isTrack.resize(MaxPFParticles);
2361  pfp_trackID.resize(MaxPFParticles);
2362  pfp_showerID.resize(MaxPFParticles);
2363  pfp_pdgCode.resize(MaxPFParticles);
2364  pfp_numClusters.resize(MaxPFParticles);
2365  pfp_clusterIDs.resize(MaxPFParticles);
2366  pfp_isNeutrino.resize(MaxPFParticles);
2367 }
2368 
2370  Resize(MaxPFParticles);
2371 
2372  nPFParticles = -999;
2373  FillWith(pfp_selfID, -999);
2374  FillWith(pfp_isPrimary, -999);
2375  FillWith(pfp_numDaughters, -999);
2376  FillWith(pfp_parentID, -999);
2377  FillWith(pfp_vertexID, -999);
2378  FillWith(pfp_isShower, -999);
2379  FillWith(pfp_isTrack, -999);
2380  FillWith(pfp_trackID, -999);
2381  FillWith(pfp_showerID, -999);
2382  FillWith(pfp_pdgCode, -999);
2383  FillWith(pfp_isNeutrino, -999);
2384  pfp_numNeutrinos = -999;
2385  FillWith(pfp_neutrinoIDs, -999);
2386 
2387  for (size_t iPFParticle = 0; iPFParticle < MaxPFParticles; ++iPFParticle){
2388  // the following are BoxedArrays;
2389  // their iterators traverse all the array dimensions
2390  FillWith(pfp_daughterIDs[iPFParticle], -999);
2391  FillWith(pfp_clusterIDs[iPFParticle], -999);
2392  }
2393 }
2394 
2396  TTree* pTree
2397  ) {
2398 
2399  if (MaxPFParticles == 0) { return; } // no PFParticles, no tree
2400 
2402 
2403  AutoResettingStringSteam sstr;
2404  sstr() << kMaxNDaughtersPerPFP;
2405  std::string MaxNDaughtersIndexStr("[" + sstr.str() + "]");
2406 
2407  sstr.str("");
2408  sstr() << kMaxNClustersPerPFP;
2409  std::string MaxNClustersIndexStr("[" + sstr.str() + "]");
2410 
2411  sstr.str("");
2412  sstr() << kMaxNPFPNeutrinos;
2413  std::string MaxNNeutrinosIndexStr("[" + sstr.str() + "]");
2414 
2415  std::string BranchName;
2416 
2417  BranchName = "nPFParticles";
2418  CreateBranch(BranchName, &nPFParticles, BranchName + "/S");
2419  std::string NPFParticleIndexStr = "[" + BranchName + "]";
2420 
2421  BranchName = "pfp_selfID";
2422  CreateBranch(BranchName, pfp_selfID, BranchName + NPFParticleIndexStr + "/S");
2423 
2424  BranchName = "pfp_isPrimary";
2425  CreateBranch(BranchName, pfp_isPrimary, BranchName + NPFParticleIndexStr + "/S");
2426 
2427  BranchName = "pfp_numDaughters";
2428  CreateBranch(BranchName, pfp_numDaughters, BranchName + NPFParticleIndexStr + "/S");
2429 
2430  BranchName = "pfp_daughterIDs";
2431  CreateBranch(BranchName, pfp_daughterIDs, BranchName + NPFParticleIndexStr + MaxNDaughtersIndexStr + "/S");
2432 
2433  BranchName = "pfp_parentID";
2434  CreateBranch(BranchName, pfp_parentID, BranchName + NPFParticleIndexStr + "/S");
2435 
2436  BranchName = "pfp_vertexID";
2437  CreateBranch(BranchName, pfp_vertexID, BranchName + NPFParticleIndexStr + "/S");
2438 
2439  BranchName = "pfp_isShower";
2440  CreateBranch(BranchName, pfp_isShower, BranchName + NPFParticleIndexStr + "/S");
2441 
2442  BranchName = "pfp_isTrack";
2443  CreateBranch(BranchName, pfp_isTrack, BranchName + NPFParticleIndexStr + "/S");
2444 
2445  BranchName = "pfp_trackID";
2446  CreateBranch(BranchName, pfp_trackID, BranchName + NPFParticleIndexStr + "/S");
2447 
2448  BranchName = "pfp_showerID";
2449  CreateBranch(BranchName, pfp_showerID, BranchName + NPFParticleIndexStr + "/S");
2450 
2451  BranchName = "pfp_pdgCode";
2452  CreateBranch(BranchName, pfp_pdgCode, BranchName + NPFParticleIndexStr + "/I");
2453 
2454  BranchName = "pfp_numClusters";
2455  CreateBranch(BranchName, pfp_numClusters, BranchName + NPFParticleIndexStr + "/S");
2456 
2457  BranchName = "pfp_clusterIDs";
2458  CreateBranch(BranchName, pfp_clusterIDs, BranchName + NPFParticleIndexStr + MaxNClustersIndexStr + "/S");
2459 
2460  BranchName = "pfp_isNeutrino";
2461  CreateBranch(BranchName, pfp_isNeutrino, BranchName + NPFParticleIndexStr + "/S");
2462 
2463  BranchName = "pfp_numNeutrinos";
2464  CreateBranch(BranchName, &pfp_numNeutrinos, BranchName + "/S");
2465 
2466  BranchName = "pfp_neutrinoIDs";
2467  CreateBranch(BranchName, pfp_neutrinoIDs, BranchName + MaxNNeutrinosIndexStr + "/S");
2468 }
2469 
2470 //------------------------------------------------------------------------------
2471 //--- AnaRootParserDataStruct::ShowerDataStruct
2472 //---
2473 
2475 (size_t nShowers)
2476 {
2477  MaxShowers = nShowers;
2478 
2479  showerID.resize(MaxShowers);
2480  shwr_bestplane.resize(MaxShowers);
2481  shwr_length.resize(MaxShowers);
2482  shwr_startdcosx.resize(MaxShowers);
2483  shwr_startdcosy.resize(MaxShowers);
2484  shwr_startdcosz.resize(MaxShowers);
2485  shwr_startx.resize(MaxShowers);
2486  shwr_starty.resize(MaxShowers);
2487  shwr_startz.resize(MaxShowers);
2488  shwr_totEng.resize(MaxShowers);
2489  shwr_dedx.resize(MaxShowers);
2490  shwr_mipEng.resize(MaxShowers);
2491  shwr_pidmvamu.resize(MaxShowers);
2492  shwr_pidmvae.resize(MaxShowers);
2493  shwr_pidmvapich.resize(MaxShowers);
2494  shwr_pidmvaphoton.resize(MaxShowers);
2495  shwr_pidmvapr.resize(MaxShowers);
2496 
2497  shwr_hasPFParticle.resize(MaxShowers);
2498  shwr_PFParticleID.resize(MaxShowers);
2499 
2500 } // dune::AnaRootParserDataStruct::ShowerDataStruct::Resize()
2501 
2503  Resize(MaxShowers);
2504  nshowers = 0;
2505 
2506  FillWith(showerID, -999 );
2507  FillWith(shwr_bestplane, -999 );
2508  FillWith(shwr_length, -999.);
2509  FillWith(shwr_startdcosx, -999.);
2510  FillWith(shwr_startdcosy, -999.);
2511  FillWith(shwr_startdcosz, -999.);
2512  FillWith(shwr_startx, -999.);
2513  FillWith(shwr_starty, -999.);
2514  FillWith(shwr_startz, -999.);
2515  FillWith(shwr_pidmvamu, -999.);
2516  FillWith(shwr_pidmvae, -999.);
2517  FillWith(shwr_pidmvapich, -999.);
2518  FillWith(shwr_pidmvaphoton, -999.);
2519  FillWith(shwr_pidmvapr, -999.);
2520 
2521  FillWith(shwr_hasPFParticle, -1);
2522  FillWith(shwr_PFParticleID, -1);
2523 
2524  for (size_t iShw = 0; iShw < MaxShowers; ++iShw){
2525  // the following are BoxedArray's;
2526  // their iterators traverse all the array dimensions
2527  FillWith(shwr_totEng[iShw], -999.);
2528  FillWith(shwr_dedx[iShw], -999.);
2529  FillWith(shwr_mipEng[iShw], -999.);
2530  } // for shower
2531 
2532 } // dune::AnaRootParserDataStruct::ShowerDataStruct::Clear()
2533 
2534 
2536 (TTree* pTree)
2537 {
2538  // here we implement the policy prescription for a missing set of showers;
2539  // this means that no shower data product was found in the event,
2540  // yet the user has accepted to go on.
2541  // We now need to mark this product in a unmistakably clear way, so that it
2542  // is not confused with a valid collection of an event where no showers
2543  // were reconstructed, not as a list of valid showers.
2544  // The prescription currently implemented is:
2545  // - have only one shower in the list;
2546  // - set the ID of that shower as -999
2547  //
2548 
2549  // first set the data structures to contain one invalid shower:
2550  SetMaxShowers(1); // includes resize to a set of one shower
2551  Clear(); // initializes all the showers in the set (one) as invalid
2552  // now set the tree addresses to the newly allocated memory;
2553  // this creates the tree branches in case they are not there yet
2554  SetAddresses(pTree);
2555 
2556  // then, set the variables so that ROOT tree knows there is one shower only
2557  nshowers = 1;
2558 
2559 } // dune::AnaRootParserDataStruct::ShowerDataStruct::MarkMissing()
2560 
2561 
2563 (TTree* pTree)
2564 {
2565  if (MaxShowers == 0) return; // no showers, no tree!
2566 
2568 
2569  AutoResettingStringSteam sstr;
2570  sstr() << kMaxShowerHits;
2571  std::string MaxShowerHitsIndexStr("[" + sstr.str() + "]");
2572 
2573  std::string ShowerLabel = Name();
2574  std::string BranchName;
2575 
2576  BranchName = "nshowers_" + ShowerLabel;
2577  CreateBranch(BranchName, &nshowers, BranchName + "/S");
2578  std::string NShowerIndexStr = "[" + BranchName + "]";
2579 
2580  BranchName = "showerID_" + ShowerLabel;
2581  CreateBranch(BranchName, showerID, BranchName + NShowerIndexStr + "/S");
2582 
2583  BranchName = "shwr_bestplane_" + ShowerLabel;
2584  CreateBranch(BranchName, shwr_bestplane, BranchName + NShowerIndexStr + "/S");
2585 
2586  BranchName = "shwr_length_" + ShowerLabel;
2587  CreateBranch(BranchName, shwr_length, BranchName + NShowerIndexStr + "/F");
2588 
2589  BranchName = "shwr_startdcosx_" + ShowerLabel;
2590  CreateBranch(BranchName, shwr_startdcosx, BranchName + NShowerIndexStr + "/F");
2591 
2592  BranchName = "shwr_startdcosy_" + ShowerLabel;
2593  CreateBranch(BranchName, shwr_startdcosy, BranchName + NShowerIndexStr + "/F");
2594 
2595  BranchName = "shwr_startdcosz_" + ShowerLabel;
2596  CreateBranch(BranchName, shwr_startdcosz, BranchName + NShowerIndexStr + "/F");
2597 
2598  BranchName = "shwr_startx_" + ShowerLabel;
2599  CreateBranch(BranchName, shwr_startx, BranchName + NShowerIndexStr + "/F");
2600 
2601  BranchName = "shwr_starty_" + ShowerLabel;
2602  CreateBranch(BranchName, shwr_starty, BranchName + NShowerIndexStr + "/F");
2603 
2604  BranchName = "shwr_startz_" + ShowerLabel;
2605  CreateBranch(BranchName, shwr_startz, BranchName + NShowerIndexStr + "/F");
2606 
2607  BranchName = "shwr_totEng_" + ShowerLabel;
2608  CreateBranch(BranchName, shwr_totEng, BranchName + NShowerIndexStr + "[3]/F");
2609 
2610  BranchName = "shwr_dedx_" + ShowerLabel;
2611  CreateBranch(BranchName, shwr_dedx, BranchName + NShowerIndexStr + "[3]/F");
2612 
2613  BranchName = "shwr_mipEng_" + ShowerLabel;
2614  CreateBranch(BranchName, shwr_mipEng, BranchName + NShowerIndexStr + "[3]/F");
2615 
2616  BranchName = "shwr_hasPFParticle_" + ShowerLabel;
2617  CreateBranch(BranchName, shwr_hasPFParticle, BranchName + NShowerIndexStr + "/S");
2618 
2619  BranchName = "shwr_PFParticleID_" + ShowerLabel;
2620  CreateBranch(BranchName, shwr_PFParticleID, BranchName + NShowerIndexStr + "/S");
2621 
2622  BranchName = "shwr_pidmvamu_" + ShowerLabel;
2623  CreateBranch(BranchName, shwr_pidmvamu, BranchName + NShowerIndexStr + "/F");
2624 
2625  BranchName = "shwr_pidmvae_" + ShowerLabel;
2626  CreateBranch(BranchName, shwr_pidmvae, BranchName + NShowerIndexStr + "/F");
2627 
2628  BranchName = "shwr_pidmvapich_" + ShowerLabel;
2629  CreateBranch(BranchName, shwr_pidmvapich, BranchName + NShowerIndexStr + "/F");
2630 
2631  BranchName = "shwr_pidmvaphoton_" + ShowerLabel;
2632  CreateBranch(BranchName, shwr_pidmvaphoton, BranchName + NShowerIndexStr + "/F");
2633 
2634  BranchName = "shwr_pidmvapr_" + ShowerLabel;
2635  CreateBranch(BranchName, shwr_pidmvapr, BranchName + NShowerIndexStr + "/F");
2636 
2637 } // dune::AnaRootParserDataStruct::ShowerDataStruct::SetAddresses()
2638 
2639 //------------------------------------------------------------------------------
2640 //--- AnaRootParserDataStruct
2641 //---
2642 
2644 
2645  // RunData.Clear();
2646  SubRunData.Clear();
2647 
2648  run = -9999;
2649  subrun = -9999;
2650  event = -9999;
2651  evttime_seconds = -9999;
2652  evttime_nanoseconds = -9999;
2653  beamtime = -9999;
2654  isdata = -99;
2655  taulife = -9999;
2656  triggernumber = 0;
2657  triggertime = -9999;
2658  beamgatetime = -9999;
2659  triggerbits = 0;
2660  potbnb = 0;
2661  potnumitgt = 0;
2662  potnumi101 = 0;
2663 
2664  no_hits = 0;
2665  no_hits_stored = 0;
2666  NHitsInAllTracks = 0;
2667 
2668  std::fill(hit_tpc, hit_tpc + sizeof(hit_tpc)/sizeof(hit_tpc[0]), -999);
2669  std::fill(hit_view, hit_view + sizeof(hit_view)/sizeof(hit_view[0]), -999);
2670  std::fill(hit_wire, hit_wire + sizeof(hit_wire)/sizeof(hit_wire[0]), -999);
2671  std::fill(hit_channel, hit_channel + sizeof(hit_channel)/sizeof(hit_channel[0]), -999);
2672  std::fill(hit_peakT, hit_peakT + sizeof(hit_peakT)/sizeof(hit_peakT[0]), -999.);
2673  std::fill(hit_chargesum, hit_chargesum + sizeof(hit_chargesum)/sizeof(hit_chargesum[0]), -999.);
2674  std::fill(hit_chargeintegral, hit_chargeintegral + sizeof(hit_chargeintegral)/sizeof(hit_chargeintegral[0]), -999.);
2675  std::fill(hit_ph, hit_ph + sizeof(hit_ph)/sizeof(hit_ph[0]), -999.);
2676  std::fill(hit_startT, hit_startT + sizeof(hit_startT)/sizeof(hit_startT[0]), -999.);
2677  std::fill(hit_endT, hit_endT + sizeof(hit_endT)/sizeof(hit_endT[0]), -999.);
2678  std::fill(hit_rms, hit_rms + sizeof(hit_rms)/sizeof(hit_rms[0]), -999.);
2679  // std::fill(hit_trueX, hit_trueX + sizeof(hit_trueX)/sizeof(hit_trueX[0]), -999.);
2680  std::fill(hit_goodnessOfFit, hit_goodnessOfFit + sizeof(hit_goodnessOfFit)/sizeof(hit_goodnessOfFit[0]), -999.);
2681  std::fill(hit_fitparamampl, hit_fitparamampl + sizeof(hit_fitparamampl)/sizeof(hit_fitparamampl[0]), -999.);
2682  std::fill(hit_fitparamt0, hit_fitparamt0 + sizeof(hit_fitparamt0)/sizeof(hit_fitparamt0[0]), -999.);
2683  std::fill(hit_fitparamtau1, hit_fitparamtau1 + sizeof(hit_fitparamtau1)/sizeof(hit_fitparamtau1[0]), -999.);
2684  std::fill(hit_fitparamtau2, hit_fitparamtau2 + sizeof(hit_fitparamtau2)/sizeof(hit_fitparamtau2[0]), -999.);
2685  std::fill(hit_multiplicity, hit_multiplicity + sizeof(hit_multiplicity)/sizeof(hit_multiplicity[0]), -999.);
2686  std::fill(hit_trueID, hit_trueID + sizeof(hit_trueID)/sizeof(hit_trueID[0]), -999.);
2687  std::fill(hit_trueEnergyMax, hit_trueEnergyMax + sizeof(hit_trueEnergyMax)/sizeof(hit_trueEnergyMax[0]), -999.);
2688  std::fill(hit_trueEnergyFraction, hit_trueEnergyFraction + sizeof(hit_trueEnergyFraction)/sizeof(hit_trueEnergyFraction[0]), -999.);
2689  std::fill(hit_trkid, hit_trkid + sizeof(hit_trkid)/sizeof(hit_trkid[0]), -999);
2690  // std::fill(hit_trkKey, hit_trkKey + sizeof(hit_trkKey)/sizeof(hit_trkKey[0]), -999);
2691  std::fill(hit_clusterid, hit_clusterid + sizeof(hit_clusterid)/sizeof(hit_clusterid[0]), -9999);
2692  // std::fill(hit_clusterKey, hit_clusterKey + sizeof(hit_clusterKey)/sizeof(hit_clusterKey[0]), -999);
2693  // std::fill(hit_nelec, hit_nelec + sizeof(hit_nelec)/sizeof(hit_nelec[0]), -999.);
2694  // std::fill(hit_energy, hit_energy + sizeof(hit_energy)/sizeof(hit_energy[0]), -999.);
2695  //raw digit information
2696 /*
2697  std::fill(rawD_ph, rawD_ph + sizeof(rawD_ph)/sizeof(rawD_ph[0]), -999.);
2698  std::fill(rawD_peakT, rawD_peakT + sizeof(rawD_peakT)/sizeof(rawD_peakT[0]), -999.);
2699  std::fill(rawD_charge, rawD_charge + sizeof(rawD_charge)/sizeof(rawD_charge[0]), -999.);
2700  std::fill(rawD_fwhh, rawD_fwhh + sizeof(rawD_fwhh)/sizeof(rawD_fwhh[0]), -999.);
2701  std::fill(rawD_rms, rawD_rms + sizeof(rawD_rms)/sizeof(rawD_rms[0]), -999.);
2702 */
2703  no_channels = 0;
2704  no_ticks = 0;
2705  no_ticksinallchannels = 0;
2706  std::fill(rawD_ADC, rawD_ADC + sizeof(rawD_ADC)/sizeof(rawD_ADC[0]), -999);
2707  std::fill(rawD_Channel, rawD_Channel + sizeof(rawD_Channel)/sizeof(rawD_Channel[0]), -999);
2708 
2709  no_recochannels=0;
2710  std::fill(recoW_Channel, recoW_Channel + sizeof(recoW_Channel)/sizeof(recoW_Channel[0]), -999);
2711  std::fill(recoW_NTicks, recoW_NTicks + sizeof(recoW_NTicks)/sizeof(recoW_NTicks[0]), -999);
2712 
2713  no_recoticksinallchannels=0;
2714  std::fill(recoW_Tick, recoW_Tick + sizeof(recoW_Tick)/sizeof(recoW_Tick[0]), -999);
2715  std::fill(recoW_ADC, recoW_ADC + sizeof(recoW_ADC)/sizeof(recoW_ADC[0]), -999);
2716 
2717  numberofphotons=0;
2718  FillWith(photons_time,-999);
2719  FillWith(photons_channel,-999);
2720 
2721  no_flashes = 0;
2722  std::fill(flash_time, flash_time + sizeof(flash_time)/sizeof(flash_time[0]), -999);
2723  std::fill(flash_pe, flash_pe + sizeof(flash_pe)/sizeof(flash_pe[0]), -999);
2724  std::fill(flash_ycenter, flash_ycenter + sizeof(flash_ycenter)/sizeof(flash_ycenter[0]), -999);
2725  std::fill(flash_zcenter, flash_zcenter + sizeof(flash_zcenter)/sizeof(flash_zcenter[0]), -999);
2726  std::fill(flash_ywidth, flash_ywidth + sizeof(flash_ywidth)/sizeof(flash_ywidth[0]), -999);
2727  std::fill(flash_zwidth, flash_zwidth + sizeof(flash_zwidth)/sizeof(flash_zwidth[0]), -999);
2728  std::fill(flash_timewidth, flash_timewidth + sizeof(flash_timewidth)/sizeof(flash_timewidth[0]), -999);
2729 
2730  no_ExternCounts = 0;
2731  std::fill(externcounts_time, externcounts_time + sizeof(externcounts_time)/sizeof(externcounts_time[0]), -999);
2732  std::fill(externcounts_id, externcounts_id + sizeof(externcounts_id)/sizeof(externcounts_id[0]), -999);
2733 
2734  nclusters = 0;
2735  std::fill(clusterId, clusterId + sizeof(clusterId)/sizeof(clusterId[0]), -999);
2736  std::fill(clusterView, clusterView + sizeof(clusterView)/sizeof(clusterView[0]), -999);
2737  std::fill(cluster_isValid, cluster_isValid + sizeof(cluster_isValid)/sizeof(cluster_isValid[0]), -1);
2738  std::fill(cluster_StartCharge, cluster_StartCharge + sizeof(cluster_StartCharge)/sizeof(cluster_StartCharge[0]), -999.);
2739  std::fill(cluster_StartAngle, cluster_StartAngle + sizeof(cluster_StartAngle)/sizeof(cluster_StartAngle[0]), -999.);
2740  std::fill(cluster_EndCharge, cluster_EndCharge + sizeof(cluster_EndCharge)/sizeof(cluster_EndCharge[0]), -999.);
2741  std::fill(cluster_EndAngle , cluster_EndAngle + sizeof(cluster_EndAngle)/sizeof(cluster_EndAngle[0]), -999.);
2742  std::fill(cluster_Integral , cluster_Integral + sizeof(cluster_Integral)/sizeof(cluster_Integral[0]), -999.);
2743  std::fill(cluster_IntegralAverage, cluster_IntegralAverage + sizeof(cluster_IntegralAverage)/sizeof(cluster_IntegralAverage[0]), -999.);
2744  std::fill(cluster_SummedADC, cluster_SummedADC + sizeof(cluster_SummedADC)/sizeof(cluster_SummedADC[0]), -999.);
2745  std::fill(cluster_SummedADCaverage, cluster_SummedADCaverage + sizeof(cluster_SummedADCaverage)/sizeof(cluster_SummedADCaverage[0]), -999.);
2746  std::fill(cluster_MultipleHitDensity, cluster_MultipleHitDensity + sizeof(cluster_MultipleHitDensity)/sizeof(cluster_MultipleHitDensity[0]), -999.);
2747  std::fill(cluster_Width, cluster_Width + sizeof(cluster_Width)/sizeof(cluster_Width[0]), -999.);
2748  std::fill(cluster_NHits, cluster_NHits + sizeof(cluster_NHits)/sizeof(cluster_NHits[0]), -999);
2749  std::fill(cluster_StartWire, cluster_StartWire + sizeof(cluster_StartWire)/sizeof(cluster_StartWire[0]), -999);
2750  std::fill(cluster_StartTick, cluster_StartTick + sizeof(cluster_StartTick)/sizeof(cluster_StartTick[0]), -999);
2751  std::fill(cluster_EndWire, cluster_EndWire + sizeof(cluster_EndWire)/sizeof(cluster_EndWire[0]), -999);
2752  std::fill(cluster_EndTick, cluster_EndTick + sizeof(cluster_EndTick)/sizeof(cluster_EndTick[0]), -999);
2753  // std::fill(cluncosmictags_tagger, cluncosmictags_tagger + sizeof(cluncosmictags_tagger)/sizeof(cluncosmictags_tagger[0]), -999);
2754  // std::fill(clucosmicscore_tagger, clucosmicscore_tagger + sizeof(clucosmicscore_tagger)/sizeof(clucosmicscore_tagger[0]), -999.);
2755  // std::fill(clucosmictype_tagger , clucosmictype_tagger + sizeof(clucosmictype_tagger )/sizeof(clucosmictype_tagger [0]), -999);
2756 
2757  nnuvtx = 0;
2758  std::fill(nuvtxx, nuvtxx + sizeof(nuvtxx)/sizeof(nuvtxx[0]), -999.);
2759  std::fill(nuvtxy, nuvtxy + sizeof(nuvtxy)/sizeof(nuvtxy[0]), -999.);
2760  std::fill(nuvtxz, nuvtxz + sizeof(nuvtxz)/sizeof(nuvtxz[0]), -999.);
2761  std::fill(nuvtxpdg, nuvtxpdg + sizeof(nuvtxpdg)/sizeof(nuvtxpdg[0]), -9999);
2762 
2763  mcevts_truth = -9999;
2764  mcevts_truthcry = -9999;
2765  std::fill(nuPDG_truth, nuPDG_truth + sizeof(nuPDG_truth)/sizeof(nuPDG_truth[0]), -999.);
2766  std::fill(ccnc_truth, ccnc_truth + sizeof(ccnc_truth)/sizeof(ccnc_truth[0]), -999.);
2767  std::fill(mode_truth, mode_truth + sizeof(mode_truth)/sizeof(mode_truth[0]), -999.);
2768  std::fill(enu_truth, enu_truth + sizeof(enu_truth)/sizeof(enu_truth[0]), -999.);
2769  std::fill(Q2_truth, Q2_truth + sizeof(Q2_truth)/sizeof(Q2_truth[0]), -999.);
2770  std::fill(W_truth, W_truth + sizeof(W_truth)/sizeof(W_truth[0]), -999.);
2771  std::fill(X_truth, X_truth + sizeof(X_truth)/sizeof(X_truth[0]), -999.);
2772  std::fill(Y_truth, Y_truth + sizeof(Y_truth)/sizeof(Y_truth[0]), -999.);
2773  std::fill(hitnuc_truth, hitnuc_truth + sizeof(hitnuc_truth)/sizeof(hitnuc_truth[0]), -999.);
2774  std::fill(nuvtxx_truth, nuvtxx_truth + sizeof(nuvtxx_truth)/sizeof(nuvtxx_truth[0]), -999.);
2775  std::fill(nuvtxy_truth, nuvtxy_truth + sizeof(nuvtxy_truth)/sizeof(nuvtxy_truth[0]), -999.);
2776  std::fill(nuvtxz_truth, nuvtxz_truth + sizeof(nuvtxz_truth)/sizeof(nuvtxz_truth[0]), -999.);
2777  std::fill(nu_dcosx_truth, nu_dcosx_truth + sizeof(nu_dcosx_truth)/sizeof(nu_dcosx_truth[0]), -999.);
2778  std::fill(nu_dcosy_truth, nu_dcosy_truth + sizeof(nu_dcosy_truth)/sizeof(nu_dcosy_truth[0]), -999.);
2779  std::fill(nu_dcosz_truth, nu_dcosz_truth + sizeof(nu_dcosz_truth)/sizeof(nu_dcosz_truth[0]), -999.);
2780  std::fill(lep_mom_truth, lep_mom_truth + sizeof(lep_mom_truth)/sizeof(lep_mom_truth[0]), -999.);
2781  std::fill(lep_dcosx_truth, lep_dcosx_truth + sizeof(lep_dcosx_truth)/sizeof(lep_dcosx_truth[0]), -999.);
2782  std::fill(lep_dcosy_truth, lep_dcosy_truth + sizeof(lep_dcosy_truth)/sizeof(lep_dcosy_truth[0]), -999.);
2783  std::fill(lep_dcosz_truth, lep_dcosz_truth + sizeof(lep_dcosz_truth)/sizeof(lep_dcosz_truth[0]), -999.);
2784 
2785  //Flux information
2786  std::fill(vx_flux, vx_flux + sizeof(vx_flux)/sizeof(vx_flux[0]), -999.);
2787  std::fill(vy_flux, vy_flux + sizeof(vy_flux)/sizeof(vy_flux[0]), -999.);
2788  std::fill(vz_flux, vz_flux + sizeof(vz_flux)/sizeof(vz_flux[0]), -999.);
2789  std::fill(pdpx_flux, pdpx_flux + sizeof(pdpx_flux)/sizeof(pdpx_flux[0]), -999.);
2790  std::fill(pdpy_flux, pdpy_flux + sizeof(pdpy_flux)/sizeof(pdpy_flux[0]), -999.);
2791  std::fill(pdpz_flux, pdpz_flux + sizeof(pdpz_flux)/sizeof(pdpz_flux[0]), -999.);
2792  std::fill(ppdxdz_flux, ppdxdz_flux + sizeof(ppdxdz_flux)/sizeof(ppdxdz_flux[0]), -999.);
2793  std::fill(ppdydz_flux, ppdydz_flux + sizeof(ppdydz_flux)/sizeof(ppdydz_flux[0]), -999.);
2794  std::fill(pppz_flux, pppz_flux + sizeof(pppz_flux)/sizeof(pppz_flux[0]), -999.);
2795  std::fill(ptype_flux, ptype_flux + sizeof(ptype_flux)/sizeof(ptype_flux[0]), -999);
2796  std::fill(ppvx_flux, ppvx_flux + sizeof(ppvx_flux)/sizeof(ppvx_flux[0]), -999.);
2797  std::fill(ppvy_flux, ppvy_flux + sizeof(ppvy_flux)/sizeof(ppvy_flux[0]), -999.);
2798  std::fill(ppvz_flux, ppvz_flux + sizeof(ppvz_flux)/sizeof(ppvz_flux[0]), -999.);
2799  std::fill(muparpx_flux, muparpx_flux + sizeof(muparpx_flux)/sizeof(muparpx_flux[0]), -999.);
2800  std::fill(muparpy_flux, muparpy_flux + sizeof(muparpy_flux)/sizeof(muparpy_flux[0]), -999.);
2801  std::fill(muparpz_flux, muparpz_flux + sizeof(muparpz_flux)/sizeof(muparpz_flux[0]), -999.);
2802  std::fill(mupare_flux, mupare_flux + sizeof(mupare_flux)/sizeof(mupare_flux[0]), -999.);
2803  std::fill(tgen_flux, tgen_flux + sizeof(tgen_flux)/sizeof(tgen_flux[0]), -999);
2804  std::fill(tgptype_flux, tgptype_flux + sizeof(tgptype_flux)/sizeof(tgptype_flux[0]), -999);
2805  std::fill(tgppx_flux, tgppx_flux + sizeof(tgppx_flux)/sizeof(tgppx_flux[0]), -999.);
2806  std::fill(tgppy_flux, tgppy_flux + sizeof(tgppy_flux)/sizeof(tgppy_flux[0]), -999.);
2807  std::fill(tgppz_flux, tgppz_flux + sizeof(tgppz_flux)/sizeof(tgppz_flux[0]), -999.);
2808  std::fill(tprivx_flux, tprivx_flux + sizeof(tprivx_flux)/sizeof(tprivx_flux[0]), -999.);
2809  std::fill(tprivy_flux, tprivy_flux + sizeof(tprivy_flux)/sizeof(tprivy_flux[0]), -999.);
2810  std::fill(tprivz_flux, tprivz_flux + sizeof(tprivz_flux)/sizeof(tprivz_flux[0]), -999.);
2811  std::fill(dk2gen_flux, dk2gen_flux + sizeof(dk2gen_flux)/sizeof(dk2gen_flux[0]), -999.);
2812  std::fill(gen2vtx_flux, gen2vtx_flux + sizeof(gen2vtx_flux)/sizeof(gen2vtx_flux[0]), -999.);
2813  std::fill(tpx_flux, tpx_flux + sizeof(tpx_flux)/sizeof(tpx_flux[0]), -999.);
2814  std::fill(tpy_flux, tpy_flux + sizeof(tpy_flux)/sizeof(tpy_flux[0]), -999.);
2815  std::fill(tpz_flux, tpz_flux + sizeof(tpz_flux)/sizeof(tpz_flux[0]), -999.);
2816  std::fill(tptype_flux, tptype_flux + sizeof(tptype_flux)/sizeof(tptype_flux[0]), -999.);
2817 
2818  genie_no_primaries = 0;
2819  cry_no_primaries = 0;
2820  proto_no_primaries = 0;
2821  generator_list_size = 0;
2822  no_primaries = 0;
2823  geant_list_size=0;
2824  geant_list_size_in_tpcAV = 0;
2825  no_mcshowers = 0;
2826  no_mctracks = 0;
2827 
2828  FillWith(pdg, -9999);
2829  FillWith(status, -9999);
2830  FillWith(Mass, -999.);
2831  FillWith(Eng, -999.);
2832  FillWith(EndE, -999.);
2833  FillWith(Px, -999.);
2834  FillWith(Py, -999.);
2835  FillWith(Pz, -999.);
2836  FillWith(P, -999.);
2837  FillWith(StartPointx, -999.);
2838  FillWith(StartPointy, -999.);
2839  FillWith(StartPointz, -999.);
2840  FillWith(StartT, -99e7);
2841  FillWith(EndT, -999.);
2842  FillWith(EndPointx, -999.);
2843  FillWith(EndPointy, -999.);
2844  FillWith(EndPointz, -999.);
2845  FillWith(EndT, -99e7);
2846  FillWith(theta, -999.);
2847  FillWith(phi, -999.);
2848  FillWith(theta_xz, -999.);
2849  FillWith(theta_yz, -999.);
2850 
2851  FillWith(pathlen_tpcAV, -999.);
2852  FillWith(inTPCActive, -9999);
2853  FillWith(TrackId_tpcAV, -9999);
2854  FillWith(PDGCode_tpcAV, -9999);
2855  FillWith(StartPointx_tpcAV, -999.);
2856  FillWith(StartPointy_tpcAV, -999.);
2857  FillWith(StartPointz_tpcAV, -999.);
2858  FillWith(StartT_tpcAV, -99e7);
2859  FillWith(StartE_tpcAV, -999.);
2860  FillWith(StartP_tpcAV, -999.);
2861  FillWith(StartPx_tpcAV, -999.);
2862  FillWith(StartPy_tpcAV, -999.);
2863  FillWith(StartPz_tpcAV, -999.);
2864  FillWith(thetastart_tpcAV, -999.);
2865  FillWith(phistart_tpcAV, -999.);
2866  FillWith(EndPointx_tpcAV, -999.);
2867  FillWith(EndPointy_tpcAV, -999.);
2868  FillWith(EndPointz_tpcAV, -999.);
2869  FillWith(EndT_tpcAV, -99e7);
2870  FillWith(EndE_tpcAV, -999.);
2871  FillWith(EndP_tpcAV, -999.);
2872  FillWith(EndPx_tpcAV, -999.);
2873  FillWith(EndPy_tpcAV, -999.);
2874  FillWith(EndPz_tpcAV, -999.);
2875  FillWith(thetaend_tpcAV, -999.);
2876  FillWith(phiend_tpcAV, -999.);
2877 
2878  FillWith(pathlen_drifted, -999.);
2879  FillWith(inTPCDrifted, -9999);
2880  FillWith(StartPointx_drifted, -999.);
2881  FillWith(StartPointy_drifted, -999.);
2882  FillWith(StartPointz_drifted, -999.);
2883  FillWith(StartT_drifted, -99e7);
2884  FillWith(StartE_drifted, -999.);
2885  FillWith(StartP_drifted, -999.);
2886  FillWith(StartPx_drifted, -999.);
2887  FillWith(StartPy_drifted, -999.);
2888  FillWith(StartPz_drifted, -999.);
2889  FillWith(EndPointx_drifted, -999.);
2890  FillWith(EndPointy_drifted, -999.);
2891  FillWith(EndPointz_drifted, -999.);
2892  FillWith(EndT_drifted, -99e7);
2893  FillWith(EndE_drifted, -999.);
2894  FillWith(EndP_drifted, -999.);
2895  FillWith(EndPx_drifted, -999.);
2896  FillWith(EndPy_drifted, -999.);
2897  FillWith(EndPz_drifted, -999.);
2898  FillWith(NumberDaughters, -9999);
2899  FillWith(Mother, -9999);
2900  FillWith(TrackId, -9999);
2901  FillWith(process_primary, -9999);
2902  FillWith(processname, "noname");
2903  FillWith(MergedId, -9999);
2904  FillWith(origin, -9999);
2905  FillWith(MCTruthIndex, -9999);
2906  FillWith(genie_primaries_pdg, -9999);
2907  FillWith(genie_Eng, -999.);
2908  FillWith(genie_Px, -999.);
2909  FillWith(genie_Py, -999.);
2910  FillWith(genie_Pz, -999.);
2911  FillWith(genie_P, -999.);
2912  FillWith(genie_status_code, -9999);
2913  FillWith(genie_mass, -999.);
2914  FillWith(genie_trackID, -9999);
2915  FillWith(genie_ND, -9999);
2916  FillWith(genie_mother, -9999);
2917  FillWith(cry_primaries_pdg, -9999);
2918  FillWith(cry_Eng, -999.);
2919  FillWith(cry_Px, -999.);
2920  FillWith(cry_Py, -999.);
2921  FillWith(cry_Pz, -999.);
2922  FillWith(cry_P, -999.);
2923  FillWith(cry_StartPointx, -999.);
2924  FillWith(cry_StartPointy, -999.);
2925  FillWith(cry_StartPointz, -999.);
2926  FillWith(cry_StartPointt, -999.);
2927  FillWith(cry_status_code, -9999);
2928  FillWith(cry_mass, -999.);
2929  FillWith(cry_trackID, -9999);
2930  FillWith(cry_ND, -9999);
2931  FillWith(cry_mother, -9999);
2932  // Start of ProtoDUNE Beam generator section
2933  FillWith(proto_isGoodParticle,-9999);
2934  FillWith(proto_vx,-999.);
2935  FillWith(proto_vy,-999.);
2936  FillWith(proto_vz,-999.);
2937  FillWith(proto_t,-999.);
2938  FillWith(proto_px,-999.);
2939  FillWith(proto_py,-999.);
2940  FillWith(proto_pz,-999.);
2941  FillWith(proto_momentum,-999.);
2942  FillWith(proto_energy,-999.);
2943  FillWith(proto_pdg,-9999);
2944  // End of ProtoDUNE Beam generator section
2945  FillWith(mcshwr_origin, -1);
2946  FillWith(mcshwr_pdg, -9999);
2947  FillWith(mcshwr_TrackId, -9999);
2948  FillWith(mcshwr_Process, "noname");
2949  FillWith(mcshwr_startX, -999.);
2950  FillWith(mcshwr_startY, -999.);
2951  FillWith(mcshwr_startZ, -999.);
2952  FillWith(mcshwr_endX, -999.);
2953  FillWith(mcshwr_endY, -999.);
2954  FillWith(mcshwr_endZ, -999.);
2955  FillWith(mcshwr_CombEngX, -999.);
2956  FillWith(mcshwr_CombEngY, -999.);
2957  FillWith(mcshwr_CombEngZ, -999.);
2958  FillWith(mcshwr_CombEngPx, -999.);
2959  FillWith(mcshwr_CombEngPy, -999.);
2960  FillWith(mcshwr_CombEngPz, -999.);
2961  FillWith(mcshwr_CombEngE, -999.);
2962  FillWith(mcshwr_dEdx, -999.);
2963  FillWith(mcshwr_StartDirX, -999.);
2964  FillWith(mcshwr_StartDirY, -999.);
2965  FillWith(mcshwr_StartDirZ, -999.);
2966  FillWith(mcshwr_isEngDeposited, -999);
2967  FillWith(mcshwr_Motherpdg, -9999);
2968  FillWith(mcshwr_MotherTrkId, -9999);
2969  FillWith(mcshwr_MotherProcess, "noname");
2970  FillWith(mcshwr_MotherstartX, -999.);
2971  FillWith(mcshwr_MotherstartY, -999.);
2972  FillWith(mcshwr_MotherstartZ, -999.);
2973  FillWith(mcshwr_MotherendX, -999.);
2974  FillWith(mcshwr_MotherendY, -999.);
2975  FillWith(mcshwr_MotherendZ, -999.);
2976  FillWith(mcshwr_Ancestorpdg, -9999);
2977  FillWith(mcshwr_AncestorTrkId, -9999);
2978  FillWith(mcshwr_AncestorProcess, "noname");
2979  FillWith(mcshwr_AncestorstartX, -999.);
2980  FillWith(mcshwr_AncestorstartY, -999.);
2981  FillWith(mcshwr_AncestorstartZ, -999.);
2982  FillWith(mcshwr_AncestorendX, -999.);
2983  FillWith(mcshwr_AncestorendY, -999.);
2984  FillWith(mcshwr_AncestorendZ, -999.);
2985 
2986  //GEANT trajectory steps
2987  geant_trajectory_size = 0;
2988 
2989  FillWith(NTrajectoryPointsPerParticle, -999);
2990 
2991  FillWith(TrajTrackId, -999);
2992  FillWith(TrajPDGCode, -999);
2993  FillWith(TrajX, -999.);
2994  FillWith(TrajY, -999.);
2995  FillWith(TrajZ, -999.);
2996  FillWith(TrajT, -999.);
2997  FillWith(TrajE, -999.);
2998  FillWith(TrajP, -999.);
2999  FillWith(TrajPx, -999.);
3000  FillWith(TrajPy, -999.);
3001  FillWith(TrajPz, -999.);
3002  FillWith(TrajTheta, -999.);
3003  FillWith(TrajPhi, -999.);
3004 
3005  //SimEnergyDeposits
3006  simenergydeposit_size = 0;
3007  particleswithsimenergydeposit_size = 0;
3008 
3009  FillWith(NSimEnergyDepositsTPCActivePerParticle, -999);
3010  FillWith(ParticleIDSimEnergyDepositsTPCActivePerParticle, 0);
3011 
3012  FillWith(SEDTPCAVTrackID, 0);
3013  FillWith(SEDTPCAVPDGCode, 0);
3014 
3015  FillWith(SEDTPCAVEnergy, -999.);
3016  FillWith(SEDTPCAVNumPhotons, -999);
3017  FillWith(SEDTPCAVNumElectrons, -999);
3018  FillWith(SEDTPCAVLength, -999.);
3019  FillWith(SEDTPCAVStartTime, -999.);
3020  FillWith(SEDTPCAVStartX, -999.);
3021  FillWith(SEDTPCAVStartY, -999.);
3022  FillWith(SEDTPCAVStartZ, -999.);
3023  FillWith(SEDTPCAVMidTime, -999.);
3024  FillWith(SEDTPCAVMidX, -999.);
3025  FillWith(SEDTPCAVMidY, -999.);
3026  FillWith(SEDTPCAVMidZ, -999.);
3027  FillWith(SEDTPCAVEndTime, -999.);
3028  FillWith(SEDTPCAVEndX, -999.);
3029  FillWith(SEDTPCAVEndY, -999.);
3030  FillWith(SEDTPCAVEndZ, -999.);
3031 
3032 
3033 
3034 
3035 
3036  // auxiliary detector information;
3037  FillWith(NAuxDets, 0);
3038  // - set to -999 all the values of each of the arrays in AuxDetID;
3039  // this auto is BoxedArray<Short_t>
3040  for (auto& partInfo: AuxDetID) FillWith(partInfo, -999);
3041  // - pythonish C++: as the previous line, for each one in a list of containers
3042  // of the same type (C++ is not python yet), using pointers to avoid copy;
3043  for (AuxDetMCData_t<Float_t>* cont: {
3044  &entryX, &entryY, &entryZ, &entryT,
3045  &exitX , &exitY , &exitZ, &exitT, &exitPx, &exitPy, &exitPz,
3046  &CombinedEnergyDep
3047  })
3048  {
3049  // this auto is BoxedArray<Float_t>
3050  for (auto& partInfo: *cont) FillWith(partInfo, -999.);
3051  } // for container
3052 
3053 } // dune::AnaRootParserDataStruct::ClearLocalData()
3054 
3055 
3057  ClearLocalData();
3058  std::for_each
3059  (TrackData.begin(), TrackData.end(), std::mem_fn(&TrackDataStruct::Clear));
3060  std::for_each
3061  (VertexData.begin(), VertexData.end(), std::mem_fn(&VertexDataStruct::Clear));
3062  std::for_each
3063  (ShowerData.begin(), ShowerData.end(), std::mem_fn(&ShowerDataStruct::Clear));
3064 } // dune::AnaRootParserDataStruct::Clear()
3065 
3066 
3068 (std::vector<std::string> const& ShowerAlgos)
3069 {
3070 
3071  size_t const nShowerAlgos = ShowerAlgos.size();
3072  ShowerData.resize(nShowerAlgos);
3073  for (size_t iAlgo = 0; iAlgo < nShowerAlgos; ++iAlgo)
3074  ShowerData[iAlgo].SetName(ShowerAlgos[iAlgo]);
3075 
3076 } // dune::AnaRootParserDataStruct::SetShowerAlgos()
3077 
3078 
3080 
3081  // minimum size is 1, so that we always have an address
3082  MaxPhotons = (size_t) std::max(nPhotons, 1);
3083 
3084  photons_time.resize(MaxPhotons);
3085  photons_channel.resize(MaxPhotons);
3086 } // dune::AnaRootParserDataStruct::ResizePhotons
3087 
3088 
3089 
3091 
3092  // minimum size is 1, so that we always have an address
3093  MaxGeneratorparticles = (size_t) std::max(nParticles, 1);
3094 
3095  TrackId.resize(MaxGeneratorparticles);
3096  pdg.resize(MaxGeneratorparticles);
3097  status.resize(MaxGeneratorparticles);
3098  Mass.resize(MaxGeneratorparticles);
3099  Eng.resize(MaxGeneratorparticles);
3100  Px.resize(MaxGeneratorparticles);
3101  Py.resize(MaxGeneratorparticles);
3102  Pz.resize(MaxGeneratorparticles);
3103  P.resize(MaxGeneratorparticles);
3104  StartPointx.resize(MaxGeneratorparticles);
3105  StartPointy.resize(MaxGeneratorparticles);
3106  StartPointz.resize(MaxGeneratorparticles);
3107  StartT.resize(MaxGeneratorparticles);
3108  theta.resize(MaxGeneratorparticles);
3109  phi.resize(MaxGeneratorparticles);
3110 } //dune::AnaRootParserDataStruct::ResizeGenerator
3111 
3113 
3114  // minimum size is 1, so that we always have an address
3115  MaxGEANTparticles = (size_t) std::max(nParticles, 1);
3116 
3117  pdg.resize(MaxGEANTparticles);
3118  status.resize(MaxGEANTparticles);
3119  inTPCActive.resize(MaxGEANTparticles);
3120  Mass.resize(MaxGEANTparticles);
3121  Eng.resize(MaxGEANTparticles);
3122  EndE.resize(MaxGEANTparticles);
3123  Px.resize(MaxGEANTparticles);
3124  Py.resize(MaxGEANTparticles);
3125  Pz.resize(MaxGEANTparticles);
3126  P.resize(MaxGEANTparticles);
3127  StartPointx.resize(MaxGEANTparticles);
3128  StartPointy.resize(MaxGEANTparticles);
3129  StartPointz.resize(MaxGEANTparticles);
3130  StartT.resize(MaxGEANTparticles);
3131  EndT.resize(MaxGEANTparticles);
3132  EndPointx.resize(MaxGEANTparticles);
3133  EndPointy.resize(MaxGEANTparticles);
3134  EndPointz.resize(MaxGEANTparticles);
3135  EndT.resize(MaxGEANTparticles);
3136  theta.resize(MaxGEANTparticles);
3137  phi.resize(MaxGEANTparticles);
3138  theta_xz.resize(MaxGEANTparticles);
3139  theta_yz.resize(MaxGEANTparticles);
3140  NumberDaughters.resize(MaxGEANTparticles);
3141  Mother.resize(MaxGEANTparticles);
3142  TrackId.resize(MaxGEANTparticles);
3143  process_primary.resize(MaxGEANTparticles);
3144  processname.resize(MaxGEANTparticles);
3145  MergedId.resize(MaxGEANTparticles);
3146  origin.resize(MaxGEANTparticles);
3147  MCTruthIndex.resize(MaxGEANTparticles);
3148 
3149  pathlen_drifted.resize(MaxGEANTparticles);
3150  inTPCDrifted.resize(MaxGEANTparticles);
3151  StartPointx_drifted.resize(MaxGEANTparticles);
3152  StartPointy_drifted.resize(MaxGEANTparticles);
3153  StartPointz_drifted.resize(MaxGEANTparticles);
3154  StartT_drifted.resize(MaxGEANTparticles);
3155  StartE_drifted.resize(MaxGEANTparticles);
3156  StartP_drifted.resize(MaxGEANTparticles);
3157  StartPx_drifted.resize(MaxGEANTparticles);
3158  StartPy_drifted.resize(MaxGEANTparticles);
3159  StartPz_drifted.resize(MaxGEANTparticles);
3160  EndPointx_drifted.resize(MaxGEANTparticles);
3161  EndPointy_drifted.resize(MaxGEANTparticles);
3162  EndPointz_drifted.resize(MaxGEANTparticles);
3163  EndT_drifted.resize(MaxGEANTparticles);
3164  EndE_drifted.resize(MaxGEANTparticles);
3165  EndP_drifted.resize(MaxGEANTparticles);
3166  EndPx_drifted.resize(MaxGEANTparticles);
3167  EndPy_drifted.resize(MaxGEANTparticles);
3168  EndPz_drifted.resize(MaxGEANTparticles);
3169 
3170  // auxiliary detector structure
3171  NAuxDets.resize(MaxGEANTparticles);
3172  AuxDetID.resize(MaxGEANTparticles);
3173  entryX.resize(MaxGEANTparticles);
3174  entryY.resize(MaxGEANTparticles);
3175  entryZ.resize(MaxGEANTparticles);
3176  entryT.resize(MaxGEANTparticles);
3177  exitX.resize(MaxGEANTparticles);
3178  exitY.resize(MaxGEANTparticles);
3179  exitZ.resize(MaxGEANTparticles);
3180  exitT.resize(MaxGEANTparticles);
3181  exitPx.resize(MaxGEANTparticles);
3182  exitPy.resize(MaxGEANTparticles);
3183  exitPz.resize(MaxGEANTparticles);
3184  CombinedEnergyDep.resize(MaxGEANTparticles);
3185 
3186  NTrajectoryPointsPerParticle.resize(MaxGEANTparticles);
3187 } // dune::AnaRootParserDataStruct::ResizeGEANT()
3188 
3190 
3191  MaxGEANTInAVparticles = (size_t) std::max(nParticlesInAV, 1);
3192 
3193  pathlen_tpcAV.resize(MaxGEANTInAVparticles);
3194  TrackId_tpcAV.resize(MaxGEANTInAVparticles);
3195  PDGCode_tpcAV.resize(MaxGEANTInAVparticles);
3196  StartPointx_tpcAV.resize(MaxGEANTInAVparticles);
3197  StartPointy_tpcAV.resize(MaxGEANTInAVparticles);
3198  StartPointz_tpcAV.resize(MaxGEANTInAVparticles);
3199  StartT_tpcAV.resize(MaxGEANTInAVparticles);
3200  StartE_tpcAV.resize(MaxGEANTInAVparticles);
3201  StartP_tpcAV.resize(MaxGEANTInAVparticles);
3202  StartPx_tpcAV.resize(MaxGEANTInAVparticles);
3203  StartPy_tpcAV.resize(MaxGEANTInAVparticles);
3204  StartPz_tpcAV.resize(MaxGEANTInAVparticles);
3205  thetastart_tpcAV.resize(MaxGEANTInAVparticles);
3206  phistart_tpcAV.resize(MaxGEANTInAVparticles);
3207  EndPointx_tpcAV.resize(MaxGEANTInAVparticles);
3208  EndPointy_tpcAV.resize(MaxGEANTInAVparticles);
3209  EndPointz_tpcAV.resize(MaxGEANTInAVparticles);
3210  EndT_tpcAV.resize(MaxGEANTInAVparticles);
3211  EndE_tpcAV.resize(MaxGEANTInAVparticles);
3212  EndP_tpcAV.resize(MaxGEANTInAVparticles);
3213  EndPx_tpcAV.resize(MaxGEANTInAVparticles);
3214  EndPy_tpcAV.resize(MaxGEANTInAVparticles);
3215  EndPz_tpcAV.resize(MaxGEANTInAVparticles);
3216  thetaend_tpcAV.resize(MaxGEANTInAVparticles);
3217  phiend_tpcAV.resize(MaxGEANTInAVparticles);
3218 } // dune::AnaRootParserDataStruct::ResizeGEANTInAV()
3219 
3221 
3222  // minimum size is 1, so that we always have an address
3223  MaxGEANTtrajectorypoints = (size_t) std::max(nTrajectoryPoints, 1);
3224 
3225  TrajTrackId.resize(MaxGEANTtrajectorypoints);
3226  TrajPDGCode.resize(MaxGEANTtrajectorypoints);
3227 
3228  TrajX.resize(MaxGEANTtrajectorypoints);
3229  TrajY.resize(MaxGEANTtrajectorypoints);
3230  TrajZ.resize(MaxGEANTtrajectorypoints);
3231  TrajT.resize(MaxGEANTtrajectorypoints);
3232  TrajE.resize(MaxGEANTtrajectorypoints);
3233  TrajP.resize(MaxGEANTtrajectorypoints);
3234  TrajPx.resize(MaxGEANTtrajectorypoints);
3235  TrajPy.resize(MaxGEANTtrajectorypoints);
3236  TrajPz.resize(MaxGEANTtrajectorypoints);
3237  TrajTheta.resize(MaxGEANTtrajectorypoints);
3238  TrajPhi.resize(MaxGEANTtrajectorypoints);
3239 
3240 } // dune::AnaRootParserDataStruct::ResizeGEANTTrajectory()
3241 
3242 void dune::AnaRootParserDataStruct::ResizeSimEnergyDepositsTPCActive(int nSimEnergyDepositsTPCActive, int nParticlesWithSimEnergyDepositsTPCActive) {
3243 
3244  // minimum size is 1, so that we always have an address
3245  MaxSimEnergyDepositsTPCActive = (size_t) std::max(nSimEnergyDepositsTPCActive, 1);
3246  MaxParticlesWithSimEnergyDepositsTPCActive = (size_t) std::max(nParticlesWithSimEnergyDepositsTPCActive, 1);
3247 
3248  std::cout << "MaxSimEnergyDepositsTPCActive: " << MaxSimEnergyDepositsTPCActive << std::endl;
3249  std::cout << "MaxParticlesWithSimEnergyDepositsTPCActive: " << MaxParticlesWithSimEnergyDepositsTPCActive << std::endl;
3250 
3251  NSimEnergyDepositsTPCActivePerParticle.resize(MaxParticlesWithSimEnergyDepositsTPCActive);
3252  ParticleIDSimEnergyDepositsTPCActivePerParticle.resize(MaxParticlesWithSimEnergyDepositsTPCActive);
3253 
3254  SEDTPCAVTrackID.resize(MaxSimEnergyDepositsTPCActive);
3255  SEDTPCAVPDGCode.resize(MaxSimEnergyDepositsTPCActive);
3256  SEDTPCAVEnergy.resize(MaxSimEnergyDepositsTPCActive);
3257  SEDTPCAVNumPhotons.resize(MaxSimEnergyDepositsTPCActive);
3258  SEDTPCAVNumElectrons.resize(MaxSimEnergyDepositsTPCActive);
3259  SEDTPCAVLength.resize(MaxSimEnergyDepositsTPCActive);
3260  SEDTPCAVStartTime.resize(MaxSimEnergyDepositsTPCActive);
3261  SEDTPCAVStartX.resize(MaxSimEnergyDepositsTPCActive);
3262  SEDTPCAVStartY.resize(MaxSimEnergyDepositsTPCActive);
3263  SEDTPCAVStartZ.resize(MaxSimEnergyDepositsTPCActive);
3264  SEDTPCAVMidTime.resize(MaxSimEnergyDepositsTPCActive);
3265  SEDTPCAVMidX.resize(MaxSimEnergyDepositsTPCActive);
3266  SEDTPCAVMidY.resize(MaxSimEnergyDepositsTPCActive);
3267  SEDTPCAVMidZ.resize(MaxSimEnergyDepositsTPCActive);
3268  SEDTPCAVEndTime.resize(MaxSimEnergyDepositsTPCActive);
3269  SEDTPCAVEndX.resize(MaxSimEnergyDepositsTPCActive);
3270  SEDTPCAVEndY.resize(MaxSimEnergyDepositsTPCActive);
3271  SEDTPCAVEndZ.resize(MaxSimEnergyDepositsTPCActive);
3272 
3273 
3274 } // dune::AnaRootParserDataStruct::ResizeSimEnergyDepositsTPCActive()
3275 
3276 
3277 
3278 
3280 
3281  // minimum size is 1, so that we always have an address
3282  MaxGeniePrimaries = (size_t) std::max(nPrimaries, 1);
3283  genie_primaries_pdg.resize(MaxGeniePrimaries);
3284  genie_Eng.resize(MaxGeniePrimaries);
3285  genie_Px.resize(MaxGeniePrimaries);
3286  genie_Py.resize(MaxGeniePrimaries);
3287  genie_Pz.resize(MaxGeniePrimaries);
3288  genie_P.resize(MaxGeniePrimaries);
3289  genie_status_code.resize(MaxGeniePrimaries);
3290  genie_mass.resize(MaxGeniePrimaries);
3291  genie_trackID.resize(MaxGeniePrimaries);
3292  genie_ND.resize(MaxGeniePrimaries);
3293  genie_mother.resize(MaxGeniePrimaries);
3294 } // dune::AnaRootParserDataStruct::ResizeGenie()
3295 
3297 
3298  cry_primaries_pdg.resize(nPrimaries);
3299  cry_Eng.resize(nPrimaries);
3300  cry_Px.resize(nPrimaries);
3301  cry_Py.resize(nPrimaries);
3302  cry_Pz.resize(nPrimaries);
3303  cry_P.resize(nPrimaries);
3304  cry_StartPointx.resize(nPrimaries);
3305  cry_StartPointy.resize(nPrimaries);
3306  cry_StartPointz.resize(nPrimaries);
3307  cry_StartPointt.resize(nPrimaries);
3308  cry_status_code.resize(nPrimaries);
3309  cry_mass.resize(nPrimaries);
3310  cry_trackID.resize(nPrimaries);
3311  cry_ND.resize(nPrimaries);
3312  cry_mother.resize(nPrimaries);
3313 
3314 } // dune::AnaRootParserDataStruct::ResizeCry()
3315 
3317 
3318  proto_isGoodParticle.resize(nPrimaries);
3319  proto_vx.resize(nPrimaries);
3320  proto_vy.resize(nPrimaries);
3321  proto_vz.resize(nPrimaries);
3322  proto_t.resize(nPrimaries);
3323  proto_px.resize(nPrimaries);
3324  proto_py.resize(nPrimaries);
3325  proto_pz.resize(nPrimaries);
3326  proto_momentum.resize(nPrimaries);
3327  proto_energy.resize(nPrimaries);
3328  proto_pdg.resize(nPrimaries);
3329 
3330 } // dune::AnaRootParserDataStruct::ResizeProto()
3331 
3333  mcshwr_origin.resize(nMCShowers);
3334  mcshwr_pdg.resize(nMCShowers);
3335  mcshwr_TrackId.resize(nMCShowers);
3336  mcshwr_Process.resize(nMCShowers);
3337  mcshwr_startX.resize(nMCShowers);
3338  mcshwr_startY.resize(nMCShowers);
3339  mcshwr_startZ.resize(nMCShowers);
3340  mcshwr_endX.resize(nMCShowers);
3341  mcshwr_endY.resize(nMCShowers);
3342  mcshwr_endZ.resize(nMCShowers);
3343  mcshwr_CombEngX.resize(nMCShowers);
3344  mcshwr_CombEngY.resize(nMCShowers);
3345  mcshwr_CombEngZ.resize(nMCShowers);
3346  mcshwr_CombEngPx.resize(nMCShowers);
3347  mcshwr_CombEngPy.resize(nMCShowers);
3348  mcshwr_CombEngPz.resize(nMCShowers);
3349  mcshwr_CombEngE.resize(nMCShowers);
3350  mcshwr_dEdx.resize(nMCShowers);
3351  mcshwr_StartDirX.resize(nMCShowers);
3352  mcshwr_StartDirY.resize(nMCShowers);
3353  mcshwr_StartDirZ.resize(nMCShowers);
3354  mcshwr_isEngDeposited.resize(nMCShowers);
3355  mcshwr_Motherpdg.resize(nMCShowers);
3356  mcshwr_MotherTrkId.resize(nMCShowers);
3357  mcshwr_MotherProcess.resize(nMCShowers);
3358  mcshwr_MotherstartX.resize(nMCShowers);
3359  mcshwr_MotherstartY.resize(nMCShowers);
3360  mcshwr_MotherstartZ.resize(nMCShowers);
3361  mcshwr_MotherendX.resize(nMCShowers);
3362  mcshwr_MotherendY.resize(nMCShowers);
3363  mcshwr_MotherendZ.resize(nMCShowers);
3364  mcshwr_Ancestorpdg.resize(nMCShowers);
3365  mcshwr_AncestorTrkId.resize(nMCShowers);
3366  mcshwr_AncestorProcess.resize(nMCShowers);
3367  mcshwr_AncestorstartX.resize(nMCShowers);
3368  mcshwr_AncestorstartY.resize(nMCShowers);
3369  mcshwr_AncestorstartZ.resize(nMCShowers);
3370  mcshwr_AncestorendX.resize(nMCShowers);
3371  mcshwr_AncestorendY.resize(nMCShowers);
3372  mcshwr_AncestorendZ.resize(nMCShowers);
3373 
3374 } // dune::AnaRootParserDataStruct::ResizeMCShower()
3375 
3377  mctrk_origin.resize(nMCTracks);
3378  mctrk_pdg.resize(nMCTracks);
3379  mctrk_TrackId.resize(nMCTracks);
3380  mctrk_Process.resize(nMCTracks);
3381  mctrk_startX.resize(nMCTracks);
3382  mctrk_startY.resize(nMCTracks);
3383  mctrk_startZ.resize(nMCTracks);
3384  mctrk_endX.resize(nMCTracks);
3385  mctrk_endY.resize(nMCTracks);
3386  mctrk_endZ.resize(nMCTracks);
3387  mctrk_startX_drifted.resize(nMCTracks);
3388  mctrk_startY_drifted.resize(nMCTracks);
3389  mctrk_startZ_drifted.resize(nMCTracks);
3390  mctrk_endX_drifted.resize(nMCTracks);
3391  mctrk_endY_drifted.resize(nMCTracks);
3392  mctrk_endZ_drifted.resize(nMCTracks);
3393  mctrk_len_drifted.resize(nMCTracks);
3394  mctrk_p_drifted.resize(nMCTracks);
3395  mctrk_px_drifted.resize(nMCTracks);
3396  mctrk_py_drifted.resize(nMCTracks);
3397  mctrk_pz_drifted.resize(nMCTracks);
3398  mctrk_Motherpdg.resize(nMCTracks);
3399  mctrk_MotherTrkId.resize(nMCTracks);
3400  mctrk_MotherProcess.resize(nMCTracks);
3401  mctrk_MotherstartX.resize(nMCTracks);
3402  mctrk_MotherstartY.resize(nMCTracks);
3403  mctrk_MotherstartZ.resize(nMCTracks);
3404  mctrk_MotherendX.resize(nMCTracks);
3405  mctrk_MotherendY.resize(nMCTracks);
3406  mctrk_MotherendZ.resize(nMCTracks);
3407  mctrk_Ancestorpdg.resize(nMCTracks);
3408  mctrk_AncestorTrkId.resize(nMCTracks);
3409  mctrk_AncestorProcess.resize(nMCTracks);
3410  mctrk_AncestorstartX.resize(nMCTracks);
3411  mctrk_AncestorstartY.resize(nMCTracks);
3412  mctrk_AncestorstartZ.resize(nMCTracks);
3413  mctrk_AncestorendX.resize(nMCTracks);
3414  mctrk_AncestorendY.resize(nMCTracks);
3415  mctrk_AncestorendZ.resize(nMCTracks);
3416 
3417 } // dune::AnaRootParserDataStruct::ResizeMCTrack()
3418 
3419 
3420 
3422  TTree* pTree,
3423  const std::vector<std::string>& trackers,
3424  const std::vector<std::string>& vertexalgos,
3425  const std::vector<std::string>& showeralgos,
3426  bool isCosmics
3427  ) {
3428  BranchCreator CreateBranch(pTree);
3429 
3430  CreateBranch("Run",&run,"run/I");
3431  CreateBranch("Subrun",&subrun,"subrun/I");
3432 // CreateBranch("EventNumberInSubrun",&event,"event/I");
3433  CreateBranch("EventNumberInRun",&event,"event/I");
3434  CreateBranch("EventTimeSeconds",&evttime_seconds,"evttime_seconds/I");
3435  CreateBranch("EventTimeNanoseconds",&evttime_nanoseconds,"evttime_nanoseconds/I");
3436  // CreateBranch("beamtime",&beamtime,"beamtime/D");
3437  // CreateBranch("pot",&SubRunData.pot,"pot/D");
3438  CreateBranch("IsData",&isdata,"isdata/B");
3439  // CreateBranch("taulife",&taulife,"taulife/D");
3440  // CreateBranch("triggernumber",&triggernumber,"triggernumber/i");
3441  // CreateBranch("triggertime",&triggertime,"triggertime/D");
3442  // CreateBranch("beamgatetime",&beamgatetime,"beamgatetime/D");
3443  // CreateBranch("triggerbits",&triggerbits,"triggerbits/i");
3444  // CreateBranch("potbnb",&potbnb,"potbnb/D");
3445  // CreateBranch("potnumitgt",&potnumitgt,"potnumitgt/D");
3446  // CreateBranch("potnumi101",&potnumi101,"potnumi101/D");
3447 
3448 if (hasRawDigitInfo()){
3449  CreateBranch("RawWaveform_NumberOfChannels",&no_channels,"no_channels/I");
3450  CreateBranch("RawWaveform_NumberOfTicks",&no_ticks,"no_ticks/I");
3451 
3452  CreateBranch("RawWaveform_Channel",rawD_Channel,"rawD_Channel[no_channels]/I");
3453 
3454  CreateBranch("RawWaveform_NumberOfTicksInAllChannels",&no_ticksinallchannels,"no_ticksinallchannels/I");
3455  CreateBranch("RawWaveform_ADC",rawD_ADC,"rawD_ADC[no_ticksinallchannels]/S");
3456 }
3457 
3458 if (hasRecobWireInfo()){
3459  CreateBranch("RecoWaveforms_NumberOfChannels",&no_recochannels,"no_recochannels/I");
3460  CreateBranch("RecoWaveform_Channel",recoW_Channel,"recoW_Channel[no_recochannels]/I");
3461  CreateBranch("RecoWaveform_NTicks",recoW_NTicks,"recoW_NTicks[no_recochannels]/I");
3462 
3463  CreateBranch("RecoWaveform_NumberOfTicksInAllChannels",&no_recoticksinallchannels,"no_recoticksinallchannels/I");
3464  CreateBranch("RecoWaveform_Tick",recoW_Tick,"recoW_Tick[no_recoticksinallchannels]/I");
3465  CreateBranch("RecoWaveform_ADC",recoW_ADC,"recoW_ADC[no_recoticksinallchannels]/F");
3466 }
3467 
3468  if (hasHitInfo()){
3469  CreateBranch("NumberOfHits",&no_hits,"no_hits/I");
3470  //CreateBranch("NumberOfHits_Stored,&no_hits_stored,"no_hits_stored/I");
3471  CreateBranch("Hit_TPC",hit_tpc,"hit_tpc[no_hits]/S");
3472  CreateBranch("Hit_View",hit_view,"hit_view[no_hits]/S");
3473  //CreateBranch("hit_wire",hit_wire,"hit_wire[no_hits]/S");
3474  CreateBranch("Hit_Channel",hit_channel,"hit_channel[no_hits]/S");
3475  CreateBranch("Hit_PeakTime",hit_peakT,"hit_peakT[no_hits]/F");
3476  CreateBranch("Hit_ChargeSummedADC",hit_chargesum,"hit_chargesum[no_hits]/F");
3477  CreateBranch("Hit_ChargeIntegral",hit_chargeintegral,"hit_chargeintegral[no_hits]/F");
3478  CreateBranch("Hit_Amplitude",hit_ph,"hit_ph[no_hits]/F");
3479  CreateBranch("Hit_StartTime",hit_startT,"hit_startT[no_hits]/F");
3480  CreateBranch("Hit_EndTime",hit_endT,"hit_endT[no_hits]/F");
3481  CreateBranch("Hit_Width",hit_rms,"hit_rms[no_hits]/F");
3482  //CreateBranch("hit_trueX",hit_trueX,"hit_trueX[no_hits]/F");
3483  CreateBranch("Hit_GoodnessOfFit",hit_goodnessOfFit,"hit_goodnessOfFit[no_hits]/F");
3484 
3485  CreateBranch("Hit_FitParameter_Amplitude", hit_fitparamampl, "hit_fitparamamp[no_hits]/F");
3486  CreateBranch("Hit_FitParameter_Offset", hit_fitparamt0, "hit_fitparamt0[no_hits]/F");
3487  CreateBranch("Hit_FitParameter_Tau1", hit_fitparamtau1, "hit_fitparamtau1[no_hits]/F");
3488  CreateBranch("Hit_FitParameter_Tau2", hit_fitparamtau2, "hit_fitparamtau2[no_hits]/F");
3489 
3490  CreateBranch("Hit_Multiplicity",hit_multiplicity,"hit_multiplicity[no_hits]/S");
3491  CreateBranch("Hit_trueID", hit_trueID, "Hit_trueID[no_hits]/I");
3492  CreateBranch("Hit_trueEnergyMax", hit_trueEnergyMax, "hit_trueEnergyMax[no_hits]/F");
3493  CreateBranch("Hit_trueEnergyFraction", hit_trueEnergyFraction, "hit_trueEnergyFraction[no_hits]/F");
3494  CreateBranch("Hit_TrackID",hit_trkid,"hit_trkid[no_hits]/S");
3495  //CreateBranch("hit_trkKey",hit_trkKey,"hit_trkKey[no_hits]/S");
3496  CreateBranch("Hit_ClusterID",hit_clusterid,"hit_clusterid[no_hits]/S");
3497  //CreateBranch("hit_clusterKey",hit_clusterKey,"hit_clusterKey[no_hits]/S");
3498  /* if (!isCosmics){
3499  CreateBranch("hit_nelec",hit_nelec,"hit_nelec[no_hits]/F");
3500  CreateBranch("hit_energy",hit_energy,"hit_energy[no_hits]/F");
3501  }
3502  */ /* if (hasRawDigitInfo()){
3503  CreateBranch("rawD_ph",rawD_ph,"rawD_ph[no_hits]/F");
3504  CreateBranch("rawD_peakT",rawD_peakT,"rawD_peakT[no_hits]/F");
3505  CreateBranch("rawD_charge",rawD_charge,"rawD_charge[no_hits]/F");
3506  CreateBranch("rawD_fwhh",rawD_fwhh,"rawD_fwhh[no_hits]/F");
3507  CreateBranch("rawD_rms",rawD_rms,"rawD_rms[no_hits]/D");
3508  }*/
3509  }
3510  /*
3511  if (hasPandoraNuVertexInfo()){
3512  CreateBranch("nnuvtx", &nnuvtx, "nnuvtx/S");
3513  CreateBranch("nuvtxx", nuvtxx, "nuvtxx[nnuvtx]/F");
3514  CreateBranch("nuvtxy", nuvtxy, "nuvtxy[nnuvtx]/F");
3515  CreateBranch("nuvtxz", nuvtxz, "nuvtxz[nnuvtx]/F");
3516  CreateBranch("nuvtxpdg", nuvtxpdg, "nuvtxpdg[nnuvtx]/S");
3517  }
3518  */
3519  if (hasClusterInfo()){
3520  CreateBranch("NumberOfClusters",&nclusters,"nclusters/S");
3521  CreateBranch("ClusterID", clusterId, "clusterId[nclusters]/S");
3522  CreateBranch("Cluster_NumberOfHits", cluster_NHits, "cluster_NHits[nclusters]/S");
3523  CreateBranch("Cluster_View", clusterView, "clusterView[nclusters]/S");
3524  CreateBranch("Cluster_ChargeIntegral", cluster_Integral, "cluster_Integral[nclusters]/F");
3525  CreateBranch("Cluster_ChargeIntegralAveragePerHit", cluster_IntegralAverage, "cluster_IntegralAverage[nclusters]/F");
3526  // CreateBranch("Cluster_SummedADC", cluster_SummedADC, "cluster_SummedADC[nclusters]/F");
3527  // CreateBranch("Cluster_SummedADCAveragePerHit", cluster_SummedADCaverage, "cluster_SummedADCaverage[nclusters]/F");
3528  // CreateBranch("Cluster_MultipleHitDensity", cluster_MultipleHitDensity, "cluster_MultipleHitDensity[nclusters]/F");
3529  // CreateBranch("Cluster_Width", cluster_Width, "cluster_Width[nclusters]/F");
3530  CreateBranch("Cluster_StartChannel", cluster_StartWire, "cluster_StartWire[nclusters]/S");
3531  CreateBranch("Cluster_StartTick", cluster_StartTick, "cluster_StartTick[nclusters]/S");
3532  CreateBranch("Cluster_EndChannel", cluster_EndWire, "cluster_EndWire[nclusters]/S");
3533  CreateBranch("Cluster_EndTick", cluster_EndTick, "cluster_EndTick[nclusters]/S");
3534  CreateBranch("Cluster_StartCharge", cluster_StartCharge, "cluster_StartCharge[nclusters]/F");
3535  CreateBranch("Cluster_StartAngle", cluster_StartAngle, "cluster_StartAngle[nclusters]/F");
3536  CreateBranch("Cluster_EndCharge", cluster_EndCharge, "cluster_EndCharge[nclusters]/F");
3537  CreateBranch("Cluster_EndAngle", cluster_EndAngle, "cluster_EndAngle[nclusters]/F");
3538 
3539  // CreateBranch("cluncosmictags_tagger", cluncosmictags_tagger, "cluncosmictags_tagger[nclusters]/S");
3540  // CreateBranch("clucosmicscore_tagger", clucosmicscore_tagger, "clucosmicscore_tagger[nclusters]/F");
3541  // CreateBranch("clucosmictype_tagger", clucosmictype_tagger, "clucosmictype_tagger[nclusters]/S");
3542  }
3543 
3544  /* if (hasFlashInfo()){
3545  CreateBranch("no_flashes",&no_flashes,"no_flashes/I");
3546  CreateBranch("flash_time",flash_time,"flash_time[no_flashes]/F");
3547  CreateBranch("flash_pe",flash_pe,"flash_pe[no_flashes]/F");
3548  CreateBranch("flash_ycenter",flash_ycenter,"flash_ycenter[no_flashes]/F");
3549  CreateBranch("flash_zcenter",flash_zcenter,"flash_zcenter[no_flashes]/F");
3550  CreateBranch("flash_ywidth",flash_ywidth,"flash_ywidth[no_flashes]/F");
3551  CreateBranch("flash_zwidth",flash_zwidth,"flash_zwidth[no_flashes]/F");
3552  CreateBranch("flash_timewidth",flash_timewidth,"flash_timewidth[no_flashes]/F");
3553  }
3554  */
3555  /* if (hasExternCountInfo()){
3556  CreateBranch("no_ExternCounts",&no_ExternCounts,"no_ExternCounts/I");
3557  CreateBranch("externcounts_time",externcounts_time,"externcounts_time[no_ExternCounts]/F");
3558  CreateBranch("externcounts_id",externcounts_id,"externcounts_id[no_ExternCounts]/F");
3559  }
3560  */
3561  /* if (hasTrackInfo()){
3562  kNTracker = trackers.size();
3563  CreateBranch("kNTracker",&kNTracker,"kNTracker/B");
3564  for(int i=0; i<kNTracker; i++){
3565  std::string TrackLabel = trackers[i];
3566 
3567  // note that if the tracker data has maximum number of tracks 0,
3568  // nothing is initialized (branches are not even created)
3569  TrackData[i].SetAddresses(pTree, TrackLabel, isCosmics);
3570  } // for trackers
3571  }
3572  */
3573  /* if (hasVertexInfo()){
3574  kNVertexAlgos = vertexalgos.size();
3575  CreateBranch("kNVertexAlgos",&kNVertexAlgos,"kNVertexAlgos/B");
3576  for(int i=0; i<kNVertexAlgos; i++){
3577  std::string VertexLabel = vertexalgos[i];
3578 
3579 // note that if the tracker data has maximum number of tracks 0,
3580 // nothing is initialized (branches are not even created)
3581 VertexData[i].SetAddresses(pTree, VertexLabel, isCosmics);
3582 } // for trackers
3583 }
3584 */
3585 if (hasShowerInfo()){
3586  kNShowerAlgos = showeralgos.size();
3587  CreateBranch("kNShowerAlgos",&kNShowerAlgos,"kNShowerAlgos/B");
3588  for(int i=0; i<kNShowerAlgos; i++){
3589  // note that if the shower data has maximum number of showers 0,
3590  // nothing is initialized (branches are not even created)
3591  ShowerData[i].SetAddresses(pTree);
3592  } // for showers
3593 } // if we have shower algos
3594 
3595 if (hasPFParticleInfo()){
3596  //CreateBranch("kNVertexAlgos",&kNVertexAlgos,"kNVertexAlgos/B"); // What would be the PFParticle equivalent of this? There's only 1 algo!
3597  PFParticleData.SetAddresses(pTree);
3598 }
3599 /*
3600  if (hasGenieInfo()){
3601  CreateBranch("mcevts_truth",&mcevts_truth,"mcevts_truth/I");
3602  CreateBranch("nuPDG_truth",nuPDG_truth,"nuPDG_truth[mcevts_truth]/I");
3603  CreateBranch("ccnc_truth",ccnc_truth,"ccnc_truth[mcevts_truth]/I");
3604  CreateBranch("mode_truth",mode_truth,"mode_truth[mcevts_truth]/I");
3605  CreateBranch("enu_truth",enu_truth,"enu_truth[mcevts_truth]/F");
3606  CreateBranch("Q2_truth",Q2_truth,"Q2_truth[mcevts_truth]/F");
3607  CreateBranch("W_truth",W_truth,"W_truth[mcevts_truth]/F");
3608  CreateBranch("X_truth",X_truth,"X_truth[mcevts_truth]/F");
3609  CreateBranch("Y_truth",Y_truth,"Y_truth[mcevts_truth]/F");
3610  CreateBranch("hitnuc_truth",hitnuc_truth,"hitnuc_truth[mcevts_truth]/I");
3611  CreateBranch("nuvtxx_truth",nuvtxx_truth,"nuvtxx_truth[mcevts_truth]/F");
3612  CreateBranch("nuvtxy_truth",nuvtxy_truth,"nuvtxy_truth[mcevts_truth]/F");
3613  CreateBranch("nuvtxz_truth",nuvtxz_truth,"nuvtxz_truth[mcevts_truth]/F");
3614  CreateBranch("nu_dcosx_truth",nu_dcosx_truth,"nu_dcosx_truth[mcevts_truth]/F");
3615  CreateBranch("nu_dcosy_truth",nu_dcosy_truth,"nu_dcosy_truth[mcevts_truth]/F");
3616  CreateBranch("nu_dcosz_truth",nu_dcosz_truth,"nu_dcosz_truth[mcevts_truth]/F");
3617  CreateBranch("lep_mom_truth",lep_mom_truth,"lep_mom_truth[mcevts_truth]/F");
3618  CreateBranch("lep_dcosx_truth",lep_dcosx_truth,"lep_dcosx_truth[mcevts_truth]/F");
3619  CreateBranch("lep_dcosy_truth",lep_dcosy_truth,"lep_dcosy_truth[mcevts_truth]/F");
3620  CreateBranch("lep_dcosz_truth",lep_dcosz_truth,"lep_dcosz_truth[mcevts_truth]/F");
3621 
3622  CreateBranch("vx_flux",vx_flux,"vx_flux[mcevts_truth]/F");
3623  CreateBranch("vy_flux",vy_flux,"vy_flux[mcevts_truth]/F");
3624  CreateBranch("vz_flux",vz_flux,"vz_flux[mcevts_truth]/F");
3625  CreateBranch("pdpx_flux",pdpx_flux,"pdpx_flux[mcevts_truth]/F");
3626  CreateBranch("pdpy_flux",pdpy_flux,"pdpy_flux[mcevts_truth]/F");
3627  CreateBranch("pdpz_flux",pdpz_flux,"pdpz_flux[mcevts_truth]/F");
3628  CreateBranch("ppdxdz_flux",ppdxdz_flux,"ppdxdz_flux[mcevts_truth]/F");
3629  CreateBranch("ppdydz_flux",ppdydz_flux,"ppdydz_flux[mcevts_truth]/F");
3630  CreateBranch("pppz_flux",pppz_flux,"pppz_flux[mcevts_truth]/F");
3631  CreateBranch("ptype_flux",ptype_flux,"ptype_flux[mcevts_truth]/I");
3632  CreateBranch("ppvx_flux",ppvx_flux,"ppvx_flux[mcevts_truth]/F");
3633  CreateBranch("ppvy_flux",ppvy_flux,"ppvy_flux[mcevts_truth]/F");
3634  CreateBranch("ppvz_flux",ppvz_flux,"ppvz_flux[mcevts_truth]/F");
3635  CreateBranch("muparpx_flux",muparpx_flux,"muparpx_flux[mcevts_truth]/F");
3636  CreateBranch("muparpy_flux",muparpy_flux,"muparpy_flux[mcevts_truth]/F");
3637  CreateBranch("muparpz_flux",muparpz_flux,"muparpz_flux[mcevts_truth]/F");
3638  CreateBranch("mupare_flux",mupare_flux,"mupare_flux[mcevts_truth]/F");
3639  CreateBranch("tgen_flux",tgen_flux,"tgen_flux[mcevts_truth]/I");
3640  CreateBranch("tgptype_flux",tgptype_flux,"tgptype_flux[mcevts_truth]/I");
3641  CreateBranch("tgppx_flux",tgppx_flux,"tgppx_flux[mcevts_truth]/F");
3642  CreateBranch("tgppy_flux",tgppy_flux,"tgppy_flux[mcevts_truth]/F");
3643  CreateBranch("tgppz_flux",tgppz_flux,"tgppz_flux[mcevts_truth]/F");
3644  CreateBranch("tprivx_flux",tprivx_flux,"tprivx_flux[mcevts_truth]/F");
3645  CreateBranch("tprivy_flux",tprivy_flux,"tprivy_flux[mcevts_truth]/F");
3646  CreateBranch("tprivz_flux",tprivz_flux,"tprivz_flux[mcevts_truth]/F");
3647  CreateBranch("dk2gen_flux",dk2gen_flux,"dk2gen_flux[mcevts_truth]/F");
3648  CreateBranch("gen2vtx_flux",gen2vtx_flux,"gen2vtx_flux[mcevts_truth]/F");
3649  CreateBranch("tpx_flux",tpx_flux,"tpx_flux[mcevts_truth]/F");
3650  CreateBranch("tpy_flux",tpy_flux,"tpy_flux[mcevts_truth]/F");
3651  CreateBranch("tpz_flux",tpz_flux,"tpz_flux[mcevts_truth]/F");
3652  CreateBranch("tptype_flux",tptype_flux,"tptype_flux[mcevts_truth]/I");
3653 
3654  CreateBranch("genie_no_primaries",&genie_no_primaries,"genie_no_primaries/I");
3655  CreateBranch("genie_primaries_pdg",genie_primaries_pdg,"genie_primaries_pdg[genie_no_primaries]/I");
3656  CreateBranch("genie_Eng",genie_Eng,"genie_Eng[genie_no_primaries]/F");
3657  CreateBranch("genie_Px",genie_Px,"genie_Px[genie_no_primaries]/F");
3658  CreateBranch("genie_Py",genie_Py,"genie_Py[genie_no_primaries]/F");
3659  CreateBranch("genie_Pz",genie_Pz,"genie_Pz[genie_no_primaries]/F");
3660  CreateBranch("genie_P",genie_P,"genie_P[genie_no_primaries]/F");
3661  CreateBranch("genie_status_code",genie_status_code,"genie_status_code[genie_no_primaries]/I");
3662  CreateBranch("genie_mass",genie_mass,"genie_mass[genie_no_primaries]/F");
3663  CreateBranch("genie_trackID",genie_trackID,"genie_trackID[genie_no_primaries]/I");
3664  CreateBranch("genie_ND",genie_ND,"genie_ND[genie_no_primaries]/I");
3665  CreateBranch("genie_mother",genie_mother,"genie_mother[genie_no_primaries]/I");
3666  }
3667  */
3668 /*
3669  if (hasCryInfo()){
3670  CreateBranch("mcevts_truthcry",&mcevts_truthcry,"mcevts_truthcry/I");
3671  CreateBranch("cry_no_primaries",&cry_no_primaries,"cry_no_primaries/I");
3672  CreateBranch("cry_primaries_pdg",cry_primaries_pdg,"cry_primaries_pdg[cry_no_primaries]/I");
3673  CreateBranch("cry_Eng",cry_Eng,"cry_Eng[cry_no_primaries]/F");
3674  CreateBranch("cry_Px",cry_Px,"cry_Px[cry_no_primaries]/F");
3675  CreateBranch("cry_Py",cry_Py,"cry_Py[cry_no_primaries]/F");
3676  CreateBranch("cry_Pz",cry_Pz,"cry_Pz[cry_no_primaries]/F");
3677  CreateBranch("cry_P",cry_P,"cry_P[cry_no_primaries]/F");
3678  CreateBranch("cry_StartPointx",cry_StartPointx,"cry_StartPointx[cry_no_primaries]/F");
3679  CreateBranch("cry_StartPointy",cry_StartPointy,"cry_StartPointy[cry_no_primaries]/F");
3680  CreateBranch("cry_StartPointz",cry_StartPointz,"cry_StartPointz[cry_no_primaries]/F");
3681  CreateBranch("cry_StartPointt",cry_StartPointt,"cry_StartPointt[cry_no_primaries]/F");
3682  CreateBranch("cry_status_code",cry_status_code,"cry_status_code[cry_no_primaries]/I");
3683  CreateBranch("cry_mass",cry_mass,"cry_mass[cry_no_primaries]/F");
3684  CreateBranch("cry_trackID",cry_trackID,"cry_trackID[cry_no_primaries]/I");
3685  CreateBranch("cry_ND",cry_ND,"cry_ND[cry_no_primaries]/I");
3686  CreateBranch("cry_mother",cry_mother,"cry_mother[cry_no_primaries]/I");
3687  }
3688  */
3689 /*
3690  if (hasProtoInfo()) {
3691  CreateBranch("proto_no_primaries",&proto_no_primaries,"proto_no_primaries/I");
3692  CreateBranch("proto_isGoodParticle",proto_isGoodParticle,"proto_isGoodParticle[proto_no_primaries]/I");
3693  CreateBranch("proto_vx",proto_vx,"proto_vx[proto_no_primaries]/F");
3694  CreateBranch("proto_vy",proto_vy,"proto_vy[proto_no_primaries]/F");
3695  CreateBranch("proto_vz",proto_vz,"proto_vz[proto_no_primaries]/F");
3696  CreateBranch("proto_t",proto_t,"proto_t[proto_no_primaries]/F");
3697  CreateBranch("proto_px",proto_px,"proto_px[proto_no_primaries]/F");
3698  CreateBranch("proto_py",proto_py,"proto_py[proto_no_primaries]/F");
3699  CreateBranch("proto_pz",proto_pz,"proto_pz[proto_no_primaries]/F");
3700  CreateBranch("proto_momentum",proto_momentum,"proto_momentum[proto_no_primaries]/F");
3701  CreateBranch("proto_energy",proto_energy,"proto_energy[proto_no_primaries]/F");
3702  CreateBranch("proto_pdg",proto_pdg,"proto_pdg[proto_no_primaries]/I");
3703  }
3704  */
3705 
3706 
3707  if (hasGeneratorInfo()){
3708  CreateBranch("MCTruth_Generator_NumberOfParticles",&generator_list_size,"generator_list_size/I");
3709  CreateBranch("MCTruth_Generator_ParticleID",TrackId,"TrackId[generator_list_size]/I");
3710  CreateBranch("MCTruth_Generator_PDGCode",pdg,"pdg[generator_list_size]/I");
3711  CreateBranch("MCTruth_Generator_Status",status,"status[generator_list_size]/I");
3712  CreateBranch("MCTruth_Generator_Mass",Mass,"Mass[generator_list_size]/F");
3713  CreateBranch("MCTruth_Generator_StartTime",StartT,"StartT[generator_list_size]/F");
3714  CreateBranch("MCTruth_Generator_StartEnergy",Eng,"Eng[generator_list_size]/F");
3715  CreateBranch("MCTruth_Generator_StartMomentum",P,"P[generator_list_size]/F");
3716  CreateBranch("MCTruth_Generator_StartPoint_X",StartPointx,"StartPointx[generator_list_size]/F");
3717  CreateBranch("MCTruth_Generator_StartPoint_Y",StartPointy,"StartPointy[generator_list_size]/F");
3718  CreateBranch("MCTruth_Generator_StartPoint_Z",StartPointz,"StartPointz[generator_list_size]/F");
3719  CreateBranch("MCTruth_Generator_StartMomentum_X",Px,"Px[generator_list_size]/F");
3720  CreateBranch("MCTruth_Generator_StartMomentum_Y",Py,"Py[generator_list_size]/F");
3721  CreateBranch("MCTruth_Generator_StartMomentum_Z",Pz,"Pz[generator_list_size]/F");
3722  CreateBranch("MCTruth_Generator_StartDirection_Theta",theta,"theta[generator_list_size]/F");
3723  CreateBranch("MCTruth_Generator_StartDirection_Phi",phi,"phi[generator_list_size]/F");
3724  }
3725 
3726  if (hasPhotonInfo()){
3727  CreateBranch("MCTruth_GEANT4_NumberOfDetectedPhotons",&numberofphotons,"numberofphotons/I");
3728  CreateBranch("MCTruth_GEANT4_DetectedPhoton_Channel",photons_channel,"photons_channel[numberofphotons]/F");
3729  CreateBranch("MCTruth_GEANT4_DetectedPhoton_Time",photons_time,"photons_time[numberofphotons]/F");
3730  }
3731 
3732  if (hasGeantInfo()){
3733  CreateBranch("MCTruth_GEANT4_NumberOfParticles",&geant_list_size,"geant_list_size/I");
3734  CreateBranch("MCTruth_GEANT4_NumberOfPrimaries",&no_primaries,"no_primaries/I");
3735  CreateBranch("MCTruth_GEANT4_ParticleID",TrackId,"TrackId[geant_list_size]/I");
3736  CreateBranch("MCTruth_GEANT4_PDGCode",pdg,"pdg[geant_list_size]/I");
3737 
3738  CreateBranch("MCTruth_GEANT4_Status",status,"status[geant_list_size]/I");
3739  CreateBranch("MCTruth_GEANT4_IsInTPCAV",inTPCActive,"inTPCActive[geant_list_size]/I");
3740  CreateBranch("MCTruth_GEANT4_NumberOfDaughterParticles",NumberDaughters,"NumberDaughters[geant_list_size]/I");
3741  CreateBranch("MCTruth_GEANT4_MotherParticle",Mother,"Mother[geant_list_size]/I");
3742  CreateBranch("MCTruth_GEANT4_Mass",Mass,"Mass[geant_list_size]/F");
3743  CreateBranch("MCTruth_GEANT4_StartPoint_X",StartPointx,"StartPointx[geant_list_size]/F");
3744  CreateBranch("MCTruth_GEANT4_StartPoint_Y",StartPointy,"StartPointy[geant_list_size]/F");
3745  CreateBranch("MCTruth_GEANT4_StartPoint_Z",StartPointz,"StartPointz[geant_list_size]/F");
3746  CreateBranch("MCTruth_GEANT4_StartTime",StartT,"StartT[geant_list_size]/F");
3747  CreateBranch("MCTruth_GEANT4_StartEnergy",Eng,"Eng[geant_list_size]/F");
3748  CreateBranch("MCTruth_GEANT4_StartMomentum",P,"P[geant_list_size]/F");
3749  CreateBranch("MCTruth_GEANT4_StartMomentum_X",Px,"Px[geant_list_size]/F");
3750  CreateBranch("MCTruth_GEANT4_StartMomentum_Y",Py,"Py[geant_list_size]/F");
3751  CreateBranch("MCTruth_GEANT4_StartMomentum_Z",Pz,"Pz[geant_list_size]/F");
3752  CreateBranch("MCTruth_GEANT4_StartDirection_Theta",theta,"theta[geant_list_size]/F");
3753  CreateBranch("MCTruth_GEANT4_StartDirection_Phi",phi,"phi[geant_list_size]/F");
3754  CreateBranch("MCTruth_GEANT4_InTPCAV_NumberOfParticles",&geant_list_size_in_tpcAV,"geant_list_size_in_tpcAV/I");
3755 // CreateBranch("MCTruth_EndEnergy",EndE,"EndE[geant_list_size]/F");
3756 // CreateBranch("MCTruth_EndPoint_X",EndPointx,"EndPointx[geant_list_size]/F");
3757 // CreateBranch("MCTruth_EndPoint_Y",EndPointy,"EndPointy[geant_list_size]/F");
3758 // CreateBranch("MCTruth_EndPoint_Z",EndPointz,"EndPointz[geant_list_size]/F");
3759 // CreateBranch("MCTruth_EndTime",EndT,"EndT[geant_list_size]/F");
3760 
3761 // CreateBranch("theta_xz",theta_xz,"theta_xz[geant_list_size]/F");
3762 // CreateBranch("theta_yz",theta_yz,"theta_yz[geant_list_size]/F");
3763 
3764  if (hasGeantInAVInfo()){
3765  CreateBranch("MCTruth_GEANT4_InTPCAV_ParticleID",TrackId_tpcAV,"TrackId_tpcAV[geant_list_size_in_tpcAV]/I");
3766  CreateBranch("MCTruth_GEANT4_InTPCAV_PDGCode",PDGCode_tpcAV,"PDGCode_tpcAV[geant_list_size_in_tpcAV]/I");
3767 
3768  CreateBranch("MCTruth_GEANT4_InTPCAV_Pathlength",pathlen_tpcAV,"pathlen_tpcAV[geant_list_size_in_tpcAV]/F");
3769  CreateBranch("MCTruth_GEANT4_InTPCAV_StartPoint_X",StartPointx_tpcAV,"StartPointx_tpcAV[geant_list_size_in_tpcAV]/F");
3770  CreateBranch("MCTruth_GEANT4_InTPCAV_StartPoint_Y",StartPointy_tpcAV,"StartPointy_tpcAV[geant_list_size_in_tpcAV]/F");
3771  CreateBranch("MCTruth_GEANT4_InTPCAV_StartPoint_Z",StartPointz_tpcAV,"StartPointz_tpcAV[geant_list_size_in_tpcAV]/F");
3772  CreateBranch("MCTruth_GEANT4_InTPCAV_StartTime",StartT_tpcAV,"StartT_tpcAV[geant_list_size_in_tpcAV]/F");
3773  CreateBranch("MCTruth_GEANT4_InTPCAV_StartEnergy",StartE_tpcAV,"StartE_tpcAV[geant_list_size_in_tpcAV]/F");
3774  CreateBranch("MCTruth_GEANT4_InTPCAV_StartMomentum",StartP_tpcAV,"StartP_tpcAV[geant_list_size_in_tpcAV]/F");
3775  CreateBranch("MCTruth_GEANT4_InTPCAV_StartMomentum_X",StartPx_tpcAV,"StartPx_tpcAV[geant_list_size_in_tpcAV]/F");
3776  CreateBranch("MCTruth_GEANT4_InTPCAV_StartMomentum_Y",StartPy_tpcAV,"StartPy_tpcAV[geant_list_size_in_tpcAV]/F");
3777  CreateBranch("MCTruth_GEANT4_InTPCAV_StartMomentum_Z",StartPz_tpcAV,"StartPz_tpcAV[geant_list_size_in_tpcAV]/F");
3778  CreateBranch("MCTruth_GEANT4_InTPCAV_StartDirection_Theta",thetastart_tpcAV,"thetastart_tpcAV[geant_list_size_in_tpcAV]/F");
3779  CreateBranch("MCTruth_GEANT4_InTPCAV_StartDirection_Phi",phistart_tpcAV,"phistart_tpcAV[geant_list_size_in_tpcAV]/F");
3780  CreateBranch("MCTruth_GEANT4_InTPCAV_EndPoint_X",EndPointx_tpcAV,"EndPointx_tpcAV[geant_list_size_in_tpcAV]/F");
3781  CreateBranch("MCTruth_GEANT4_InTPCAV_EndPoint_Y",EndPointy_tpcAV,"EndPointy_tpcAV[geant_list_size_in_tpcAV]/F");
3782  CreateBranch("MCTruth_GEANT4_InTPCAV_EndPoint_Z",EndPointz_tpcAV,"EndPointz_tpcAV[geant_list_size_in_tpcAV]/F");
3783  CreateBranch("MCTruth_GEANT4_InTPCAV_EndTime",EndT_tpcAV,"EndT_tpcAV[geant_list_size_in_tpcAV]/F");
3784  CreateBranch("MCTruth_GEANT4_InTPCAV_EndEnergy",EndE_tpcAV,"EndE_tpcAV[geant_list_size_in_tpcAV]/F");
3785  CreateBranch("MCTruth_GEANT4_InTPCAV_EndMomentum",EndP_tpcAV,"EndP_tpcAV[geant_list_size_in_tpcAV]/F");
3786  CreateBranch("MCTruth_GEANT4_InTPCAV_EndMomentum_X",EndPx_tpcAV,"EndPx_tpcAV[geant_list_size_in_tpcAV]/F");
3787  CreateBranch("MCTruth_GEANT4_InTPCAV_EndMomentum_Y",EndPy_tpcAV,"EndPy_tpcAV[geant_list_size_in_tpcAV]/F");
3788  CreateBranch("MCTruth_GEANT4_InTPCAV_EndMomentum_Z",EndPz_tpcAV,"EndPz_tpcAV[geant_list_size_in_tpcAV]/F");
3789  CreateBranch("MCTruth_GEANT4_InTPCAV_EndDirection_Theta",thetaend_tpcAV,"thetaend_tpcAV[geant_list_size_in_tpcAV]/F");
3790  CreateBranch("MCTruth_GEANT4_InTPCAV_EndDirection_Phi",phiend_tpcAV,"phiend_tpcAV[geant_list_size_in_tpcAV]/F");
3791 }
3792 
3793 
3794 /*
3795  CreateBranch("pathlen_drifted",pathlen_drifted,"pathlen_drifted[geant_list_size]/F");
3796  CreateBranch("inTPCDrifted",inTPCDrifted,"inTPCDrifted[geant_list_size]/I");
3797  CreateBranch("StartPointx_drifted",StartPointx_drifted,"StartPointx_drifted[geant_list_size]/F");
3798  CreateBranch("StartPointy_drifted",StartPointy_drifted,"StartPointy_drifted[geant_list_size]/F");
3799  CreateBranch("StartPointz_drifted",StartPointz_drifted,"StartPointz_drifted[geant_list_size]/F");
3800  CreateBranch("StartT_drifted",StartT_drifted,"StartT_drifted[geant_list_size]/F");
3801  CreateBranch("StartE_drifted",StartE_drifted,"StartE_drifted[geant_list_size]/F");
3802  CreateBranch("StartP_drifted",StartP_drifted,"StartP_drifted[geant_list_size]/F");
3803  CreateBranch("StartPx_drifted",StartPx_drifted,"StartPx_drifted[geant_list_size]/F");
3804  CreateBranch("StartPy_drifted",StartPy_drifted,"StartPy_drifted[geant_list_size]/F");
3805  CreateBranch("StartPz_drifted",StartPz_drifted,"StartPz_drifted[geant_list_size]/F");
3806  CreateBranch("EndPointx_drifted",EndPointx_drifted,"EndPointx_drifted[geant_list_size]/F");
3807  CreateBranch("EndPointy_drifted",EndPointy_drifted,"EndPointy_drifted[geant_list_size]/F");
3808  CreateBranch("EndPointz_drifted",EndPointz_drifted,"EndPointz_drifted[geant_list_size]/F");
3809  CreateBranch("EndT_drifted",EndT_drifted,"EndT_drifted[geant_list_size]/F");
3810  CreateBranch("EndE_drifted",EndE_drifted,"EndE_drifted[geant_list_size]/F");
3811  CreateBranch("EndP_drifted",EndP_drifted,"EndP_drifted[geant_list_size]/F");
3812  CreateBranch("EndPx_drifted",EndPx_drifted,"EndPx_drifted[geant_list_size]/F");
3813  CreateBranch("EndPy_drifted",EndPy_drifted,"EndPy_drifted[geant_list_size]/F");
3814  CreateBranch("EndPz_drifted",EndPz_drifted,"EndPz_drifted[geant_list_size]/F");
3815 */
3816 
3817 /*
3818  CreateBranch("TrackId",TrackId,"TrackId[geant_list_size]/I");
3819  CreateBranch("MergedId", MergedId, "MergedId[geant_list_size]/I");
3820  CreateBranch("origin", origin, "origin[geant_list_size]/I");
3821  CreateBranch("MCTruthIndex", MCTruthIndex, "MCTruthIndex[geant_list_size]/I");
3822  CreateBranch("process_primary",process_primary,"process_primary[geant_list_size]/I");
3823  CreateBranch("processname", processname);
3824 */
3825 }
3826 
3827 if(hasGeantTrajectoryInfo()){
3828  CreateBranch("MCTruth_GEANT4_TotalNumberOfTrajectoryStepsForAllParticles",&geant_trajectory_size,"geant_trajectory_size/I");
3829  CreateBranch("MCTruth_GEANT4_NumberOfTrajectoryStepsPerParticle",NTrajectoryPointsPerParticle,"NTrajectoryPointsPerParticle[geant_list_size]/I");
3830 
3831  CreateBranch("MCTruth_GEANT4_TrajectoryStep_ParticleID",TrajTrackId,"TrajTrackId[geant_trajectory_size]/I");
3832  CreateBranch("MCTruth_GEANT4_TrajectoryStep_PDGCode",TrajPDGCode,"TrajPDGCode[geant_trajectory_size]/I");
3833  CreateBranch("MCTruth_GEANT4_TrajectoryStep_Point_X",TrajX,"TrajX[geant_trajectory_size]/F");
3834  CreateBranch("MCTruth_GEANT4_TrajectoryStep_Point_Y",TrajY,"TrajY[geant_trajectory_size]/F");
3835  CreateBranch("MCTruth_GEANT4_TrajectoryStep_Point_Z",TrajZ,"TrajZ[geant_trajectory_size]/F");
3836  CreateBranch("MCTruth_GEANT4_TrajectoryStep_Time",TrajT,"TrajT[geant_trajectory_size]/F");
3837  CreateBranch("MCTruth_GEANT4_TrajectoryStep_Energy",TrajE,"TrajE[geant_trajectory_size]/F");
3838  CreateBranch("MCTruth_GEANT4_TrajectoryStep_Momentum",TrajP,"TrajP[geant_trajectory_size]/F");
3839  CreateBranch("MCTruth_GEANT4_TrajectoryStep_Momentum_X",TrajPx,"TrajPx[geant_trajectory_size]/F");
3840  CreateBranch("MCTruth_GEANT4_TrajectoryStep_Momentum_Y",TrajPy,"TrajPy[geant_trajectory_size]/F");
3841  CreateBranch("MCTruth_GEANT4_TrajectoryStep_Momentum_Z",TrajPz,"TrajPz[geant_trajectory_size]/F");
3842  CreateBranch("MCTruth_GEANT4_TrajectoryStep_Direction_Theta",TrajTheta,"TrajTheta[geant_trajectory_size]/F");
3843  CreateBranch("MCTruth_GEANT4_TrajectoryStep_Direction_Phi",TrajPhi,"TrajPhi[geant_trajectory_size]/F");
3844 }
3845 
3846 if(hasSimEnergyDepositTPCActiveInfo()){
3847  CreateBranch("MCTruth_GEANT4_TotalNumberOfSEDInTPCAVForAllParticles",&simenergydeposit_size,"simenergydeposit_size/I");
3848  CreateBranch("MCTruth_GEANT4_NumberOfParticlesWithSEDInTPCAV",&particleswithsimenergydeposit_size,"particleswithsimenergydeposit_size/I");
3849 
3850  CreateBranch("MCTruth_GEANT4_ParticlesWithSEDInTPCAV_NumberOfSED",NSimEnergyDepositsTPCActivePerParticle,"NSimEnergyDepositsTPCActivePerParticle[particleswithsimenergydeposit_size]/I");
3851  CreateBranch("MCTruth_GEANT4_ParticlesWithSEDInTPCAV_ParticleID",ParticleIDSimEnergyDepositsTPCActivePerParticle,"ParticleIDSimEnergyDepositsTPCActivePerParticle[particleswithsimenergydeposit_size]/I");
3852 
3853  CreateBranch("MCTruth_GEANT4_SEDInTPCAV_ParticleID",SEDTPCAVTrackID,"SEDTPCAVTrackID[simenergydeposit_size]/I");
3854  CreateBranch("MCTruth_GEANT4_SEDInTPCAV_PDGCode",SEDTPCAVPDGCode,"SEDTPCAVPDGCode[simenergydeposit_size]/I");
3855  CreateBranch("MCTruth_GEANT4_SEDInTPCAV_EnergyDeposition",SEDTPCAVEnergy,"SEDTPCAVEnergy[simenergydeposit_size]/F");
3856  CreateBranch("MCTruth_GEANT4_SEDInTPCAV_NumberOfPhotons",SEDTPCAVNumPhotons,"SEDTPCAVNumPhotons[simenergydeposit_size]/I");
3857  CreateBranch("MCTruth_GEANT4_SEDInTPCAV_NumberOfElectrons",SEDTPCAVNumElectrons,"SEDTPCAVNumElectrons[simenergydeposit_size]/I");
3858  CreateBranch("MCTruth_GEANT4_SEDInTPCAV_Length",SEDTPCAVLength,"SEDTPCAVLength[simenergydeposit_size]/F");
3859  CreateBranch("MCTruth_GEANT4_SEDInTPCAV_StartTime",SEDTPCAVStartTime,"SEDTPCAVStartTime[simenergydeposit_size]/F");
3860  CreateBranch("MCTruth_GEANT4_SEDInTPCAV_StartPoint_X",SEDTPCAVStartX,"SEDTPCAVStartX[simenergydeposit_size]/F");
3861  CreateBranch("MCTruth_GEANT4_SEDInTPCAV_StartPoint_Y",SEDTPCAVStartY,"SEDTPCAVStartY[simenergydeposit_size]/F");
3862  CreateBranch("MCTruth_GEANT4_SEDInTPCAV_StartPoint_Z",SEDTPCAVStartZ,"SEDTPCAVStartZ[simenergydeposit_size]/F");
3863  CreateBranch("MCTruth_GEANT4_SEDInTPCAV_MidTime",SEDTPCAVMidTime,"SEDTPCAVMidTime[simenergydeposit_size]/F");
3864  CreateBranch("MCTruth_GEANT4_SEDInTPCAV_MidPoint_X",SEDTPCAVMidX,"SEDTPCAVMidX[simenergydeposit_size]/F");
3865  CreateBranch("MCTruth_GEANT4_SEDInTPCAV_MidPoint_Y",SEDTPCAVMidY,"SEDTPCAVMidY[simenergydeposit_size]/F");
3866  CreateBranch("MCTruth_GEANT4_SEDInTPCAV_MidPoint_Z",SEDTPCAVMidZ,"SEDTPCAVMidZ[simenergydeposit_size]/F");
3867  CreateBranch("MCTruth_GEANT4_SEDInTPCAV_EndTime",SEDTPCAVEndTime,"SEDTPCAVEndTime[simenergydeposit_size]/F");
3868  CreateBranch("MCTruth_GEANT4_SEDInTPCAV_EndPoint_X",SEDTPCAVEndX,"SEDTPCAVEndX[simenergydeposit_size]/F");
3869  CreateBranch("MCTruth_GEANT4_SEDInTPCAV_EndPoint_Y",SEDTPCAVEndY,"SEDTPCAVEndY[simenergydeposit_size]/F");
3870  CreateBranch("MCTruth_GEANT4_SEDInTPCAV_EndPoint_Z",SEDTPCAVEndZ,"SEDTPCAVEndZ[simenergydeposit_size]/F");
3871 }
3872 
3873 /*
3874  if (hasMCShowerInfo()){
3875  CreateBranch("no_mcshowers",&no_mcshowers,"no_mcshowers/I");
3876  CreateBranch("mcshwr_origin",mcshwr_origin,"mcshwr_origin[no_mcshowers]/I");
3877  CreateBranch("mcshwr_pdg",mcshwr_pdg,"mcshwr_pdg[no_mcshowers]/I");
3878  CreateBranch("mcshwr_TrackId",mcshwr_TrackId,"mcshwr_TrackId[no_mcshowers]/I");
3879  CreateBranch("mcshwr_Process",mcshwr_Process);
3880  CreateBranch("mcshwr_startX",mcshwr_startX,"mcshwr_startX[no_mcshowers]/F");
3881  CreateBranch("mcshwr_startY",mcshwr_startY,"mcshwr_startY[no_mcshowers]/F");
3882  CreateBranch("mcshwr_startZ",mcshwr_startZ,"mcshwr_startZ[no_mcshowers]/F");
3883  CreateBranch("mcshwr_endX",mcshwr_endX,"mcshwr_endX[no_mcshowers]/F");
3884  CreateBranch("mcshwr_endY",mcshwr_endY,"mcshwr_endY[no_mcshowers]/F");
3885  CreateBranch("mcshwr_endZ",mcshwr_endZ,"mcshwr_endZ[no_mcshowers]/F");
3886  CreateBranch("mcshwr_CombEngX",mcshwr_CombEngX,"mcshwr_CombEngX[no_mcshowers]/F");
3887  CreateBranch("mcshwr_CombEngY",mcshwr_CombEngY,"mcshwr_CombEngY[no_mcshowers]/F");
3888  CreateBranch("mcshwr_CombEngZ",mcshwr_CombEngZ,"mcshwr_CombEngZ[no_mcshowers]/F");
3889  CreateBranch("mcshwr_CombEngPx",mcshwr_CombEngPx,"mcshwr_CombEngPx[no_mcshowers]/F");
3890  CreateBranch("mcshwr_CombEngPy",mcshwr_CombEngPy,"mcshwr_CombEngPy[no_mcshowers]/F");
3891  CreateBranch("mcshwr_CombEngPz",mcshwr_CombEngPz,"mcshwr_CombEngPz[no_mcshowers]/F");
3892  CreateBranch("mcshwr_CombEngE",mcshwr_CombEngE,"mcshwr_CombEngE[no_mcshowers]/F");
3893  CreateBranch("mcshwr_dEdx",mcshwr_dEdx,"mcshwr_dEdx[no_mcshowers]/F");
3894  CreateBranch("mcshwr_StartDirX",mcshwr_StartDirX,"mcshwr_StartDirX[no_mcshowers]/F");
3895  CreateBranch("mcshwr_StartDirY",mcshwr_StartDirY,"mcshwr_StartDirY[no_mcshowers]/F");
3896  CreateBranch("mcshwr_StartDirZ",mcshwr_StartDirZ,"mcshwr_StartDirZ[no_mcshowers]/F");
3897  CreateBranch("mcshwr_isEngDeposited",mcshwr_isEngDeposited,"mcshwr_isEngDeposited[no_mcshowers]/I");
3898  CreateBranch("mcshwr_Motherpdg",mcshwr_Motherpdg,"mcshwr_Motherpdg[no_mcshowers]/I");
3899  CreateBranch("mcshwr_MotherTrkId",mcshwr_MotherTrkId,"mcshwr_MotherTrkId[no_mcshowers]/I");
3900  CreateBranch("mcshwr_MotherProcess",mcshwr_MotherProcess);
3901  CreateBranch("mcshwr_MotherstartX",mcshwr_MotherstartX,"mcshwr_MotherstartX[no_mcshowers]/F");
3902  CreateBranch("mcshwr_MotherstartY",mcshwr_MotherstartY,"mcshwr_MotherstartY[no_mcshowers]/F");
3903  CreateBranch("mcshwr_MotherstartZ",mcshwr_MotherstartZ,"mcshwr_MotherstartZ[no_mcshowers]/F");
3904  CreateBranch("mcshwr_MotherendX",mcshwr_MotherendX,"mcshwr_MotherendX[no_mcshowers]/F");
3905  CreateBranch("mcshwr_MotherendY",mcshwr_MotherendY,"mcshwr_MotherendY[no_mcshowers]/F");
3906  CreateBranch("mcshwr_MotherendZ",mcshwr_MotherendZ,"mcshwr_MotherendZ[no_mcshowers]/F");
3907  CreateBranch("mcshwr_Ancestorpdg",mcshwr_Ancestorpdg,"mcshwr_Ancestorpdg[no_mcshowers]/I");
3908  CreateBranch("mcshwr_AncesotorTrkId",mcshwr_AncestorTrkId,"mcshwr_AncestorTrkId[no_mcshowers]/I");
3909  CreateBranch("mcshwr_AncesotorProcess",mcshwr_AncestorProcess);
3910  CreateBranch("mcshwr_AncestorstartX",mcshwr_AncestorstartX,"mcshwr_AncestorstartX[no_mcshowers]/F");
3911  CreateBranch("mcshwr_AncestorstartY",mcshwr_AncestorstartY,"mcshwr_AncestorstartY[no_mcshowers]/F");
3912  CreateBranch("mcshwr_AncestorstartZ",mcshwr_AncestorstartZ,"mcshwr_AncestorstartZ[no_mcshowers]/F");
3913  CreateBranch("mcshwr_AncestorendX",mcshwr_AncestorendX,"mcshwr_AncestorendX[no_mcshowers]/F");
3914  CreateBranch("mcshwr_AncestorendY",mcshwr_AncestorendY,"mcshwr_AncestorendY[no_mcshowers]/F");
3915  CreateBranch("mcshwr_AncestorendZ",mcshwr_AncestorendZ,"mcshwr_AncestorendZ[no_mcshowers]/F");
3916  }
3917  */
3918 /*
3919  if (hasMCTrackInfo()){
3920  CreateBranch("no_mctracks",&no_mctracks,"no_mctracks/I");
3921  CreateBranch("mctrk_origin",mctrk_origin,"mctrk_origin[no_mctracks]/I");
3922  CreateBranch("mctrk_pdg",mctrk_pdg,"mctrk_pdg[no_mctracks]/I");
3923  CreateBranch("mctrk_TrackId",mctrk_TrackId,"mctrk_TrackId[no_mctracks]/I");
3924  CreateBranch("mctrk_Process",mctrk_Process);
3925  CreateBranch("mctrk_startX",mctrk_startX,"mctrk_startX[no_mctracks]/F");
3926  CreateBranch("mctrk_startY",mctrk_startY,"mctrk_startY[no_mctracks]/F");
3927  CreateBranch("mctrk_startZ",mctrk_startZ,"mctrk_startZ[no_mctracks]/F");
3928  CreateBranch("mctrk_endX",mctrk_endX,"mctrk_endX[no_mctracks]/F");
3929  CreateBranch("mctrk_endY",mctrk_endY,"mctrk_endY[no_mctracks]/F");
3930  CreateBranch("mctrk_endZ",mctrk_endZ,"mctrk_endZ[no_mctracks]/F");
3931  CreateBranch("mctrk_startX_drifted",mctrk_startX_drifted,"mctrk_startX_drifted[no_mctracks]/F");
3932  CreateBranch("mctrk_startY_drifted",mctrk_startY_drifted,"mctrk_startY_drifted[no_mctracks]/F");
3933  CreateBranch("mctrk_startZ_drifted",mctrk_startZ_drifted,"mctrk_startZ_drifted[no_mctracks]/F");
3934  CreateBranch("mctrk_endX_drifted",mctrk_endX_drifted,"mctrk_endX_drifted[no_mctracks]/F");
3935  CreateBranch("mctrk_endY_drifted",mctrk_endY_drifted,"mctrk_endY_drifted[no_mctracks]/F");
3936  CreateBranch("mctrk_endZ_drifted",mctrk_endZ_drifted,"mctrk_endZ_drifted[no_mctracks]/F");
3937  CreateBranch("mctrk_len_drifted",mctrk_len_drifted,"mctrk_len_drifted[no_mctracks]/F");
3938  CreateBranch("mctrk_p_drifted",mctrk_p_drifted,"mctrk_p_drifted[no_mctracks]/F");
3939  CreateBranch("mctrk_px_drifted",mctrk_px_drifted,"mctrk_px_drifted[no_mctracks]/F");
3940  CreateBranch("mctrk_py_drifted",mctrk_py_drifted,"mctrk_py_drifted[no_mctracks]/F");
3941  CreateBranch("mctrk_pz_drifted",mctrk_pz_drifted,"mctrk_pz_drifted[no_mctracks]/F");
3942  CreateBranch("mctrk_Motherpdg",mctrk_Motherpdg,"mctrk_Motherpdg[no_mctracks]/I");
3943  CreateBranch("mctrk_MotherTrkId",mctrk_MotherTrkId,"mctrk_MotherTrkId[no_mctracks]/I");
3944  CreateBranch("mctrk_MotherProcess",mctrk_MotherProcess);
3945  CreateBranch("mctrk_MotherstartX",mctrk_MotherstartX,"mctrk_MotherstartX[no_mctracks]/F");
3946  CreateBranch("mctrk_MotherstartY",mctrk_MotherstartY,"mctrk_MotherstartY[no_mctracks]/F");
3947  CreateBranch("mctrk_MotherstartZ",mctrk_MotherstartZ,"mctrk_MotherstartZ[no_mctracks]/F");
3948  CreateBranch("mctrk_MotherendX",mctrk_MotherendX,"mctrk_MotherendX[no_mctracks]/F");
3949  CreateBranch("mctrk_MotherendY",mctrk_MotherendY,"mctrk_MotherendY[no_mctracks]/F");
3950  CreateBranch("mctrk_MotherendZ",mctrk_MotherendZ,"mctrk_MotherendZ[no_mctracks]/F");
3951  CreateBranch("mctrk_Ancestorpdg",mctrk_Ancestorpdg,"mctrk_Ancestorpdg[no_mctracks]/I");
3952  CreateBranch("mctrk_AncesotorTrkId",mctrk_AncestorTrkId,"mctrk_AncestorTrkId[no_mctracks]/I");
3953  CreateBranch("mctrk_AncesotorProcess",mctrk_AncestorProcess);
3954  CreateBranch("mctrk_AncestorstartX",mctrk_AncestorstartX,"mctrk_AncestorstartX[no_mctracks]/F");
3955  CreateBranch("mctrk_AncestorstartY",mctrk_AncestorstartY,"mctrk_AncestorstartY[no_mctracks]/F");
3956  CreateBranch("mctrk_AncestorstartZ",mctrk_AncestorstartZ,"mctrk_AncestorstartZ[no_mctracks]/F");
3957  CreateBranch("mctrk_AncestorendX",mctrk_AncestorendX,"mctrk_AncestorendX[no_mctracks]/F");
3958  CreateBranch("mctrk_AncestorendY",mctrk_AncestorendY,"mctrk_AncestorendY[no_mctracks]/F");
3959  CreateBranch("mctrk_AncestorendZ",mctrk_AncestorendZ,"mctrk_AncestorendZ[no_mctracks]/F");
3960  }
3961  */
3962 /*
3963  if (hasAuxDetector()) {
3964 // Geant information is required to fill aux detector information.
3965 // if fSaveGeantInfo is not set to true, show an error message and quit!
3966 if (!hasGeantInfo()){
3967 throw art::Exception(art::errors::Configuration)
3968 << "Saving Auxiliary detector information requies saving GEANT information, "
3969 <<"please set fSaveGeantInfo flag to true in your fhicl file and rerun.\n";
3970 }
3971 std::ostringstream sstr;
3972 sstr << "[" << kMaxAuxDets << "]";
3973 std::string MaxAuxDetIndexStr = sstr.str();
3974 CreateBranch("NAuxDets", NAuxDets, "NAuxDets[geant_list_size]/s");
3975 CreateBranch("AuxDetID", AuxDetID, "AuxDetID[geant_list_size]" + MaxAuxDetIndexStr + "/S");
3976 CreateBranch("AuxDetEntryX", entryX, "AuxDetEntryX[geant_list_size]" + MaxAuxDetIndexStr + "/F");
3977 CreateBranch("AuxDetEntryY", entryY, "AuxDetEntryY[geant_list_size]" + MaxAuxDetIndexStr + "/F");
3978 CreateBranch("AuxDetEntryZ", entryZ, "AuxDetEntryZ[geant_list_size]" + MaxAuxDetIndexStr + "/F");
3979 CreateBranch("AuxDetEntryT", entryT, "AuxDetEntryT[geant_list_size]" + MaxAuxDetIndexStr + "/F");
3980 CreateBranch("AuxDetExitX", exitX, "AuxDetExitX[geant_list_size]" + MaxAuxDetIndexStr + "/F");
3981 CreateBranch("AuxDetExitY", exitY, "AuxDetExitY[geant_list_size]" + MaxAuxDetIndexStr + "/F");
3982 CreateBranch("AuxDetExitZ", exitZ, "AuxDetExitZ[geant_list_size]" + MaxAuxDetIndexStr + "/F");
3983 CreateBranch("AuxDetExitT", exitT, "AuxDetExitT[geant_list_size]" + MaxAuxDetIndexStr + "/F");
3984 CreateBranch("AuxDetExitPx", exitPx, "AuxDetExitPx[geant_list_size]" + MaxAuxDetIndexStr + "/F");
3985 CreateBranch("AuxDetExitPy", exitPy, "AuxDetExitPy[geant_list_size]" + MaxAuxDetIndexStr + "/F");
3986 CreateBranch("AuxDetExitPz", exitPz, "AuxDetExitPz[geant_list_size]" + MaxAuxDetIndexStr + "/F");
3987 CreateBranch("CombinedEnergyDep", CombinedEnergyDep,
3988 "CombinedEnergyDep[geant_list_size]" + MaxAuxDetIndexStr + "/F");
3989 } // if hasAuxDetector
3990 */
3991 } // dune::AnaRootParserDataStruct::SetAddresses()
3992 
3993 
3994 //------------------------------------------------------------------------------
3995 //--- AnaRootParser
3996 //---
3997 
3999  EDAnalyzer(pset),
4000  fTree(nullptr),
4001  // fPOT(nullptr),
4002 
4003  fLogLevel (pset.get< short >("LogLevel") ),
4004  fEventsPerSubrun (pset.get< short >("EventsPerSubrun") ),
4005  fRawDigitModuleLabel (pset.get< std::string >("RawDigitModuleLabel") ),
4006  fHitsModuleLabel (pset.get< std::string >("HitsModuleLabel") ),
4007  fPhotonPropS1ModuleLabel (pset.get< std::string >("PhotonPropS1ModuleLabel") ),
4008  fElecDriftModuleLabel (pset.get< std::string >("ElecDriftModuleLabel") ),
4009  fCalDataModuleLabel (pset.get< std::string >("CalDataModuleLabel") ),
4010  fGenieGenModuleLabel (pset.get< std::string >("GenieGenModuleLabel") ),
4011  fCryGenModuleLabel (pset.get< std::string >("CryGenModuleLabel") ),
4012  fProtoGenModuleLabel (pset.get< std::string >("ProtoGenModuleLabel") ),
4013  fG4ModuleLabel (pset.get< std::string >("G4ModuleLabel") ),
4014  fSimEnergyDepositTPCActiveLabel (pset.get< std::string >("SimEnergyDepositTPCActiveLabel") ),
4015  fClusterModuleLabel (pset.get< std::string >("ClusterModuleLabel") ),
4016  fPandoraNuVertexModuleLabel (pset.get< std::string >("PandoraNuVertexModuleLabel") ),
4017  fOpFlashModuleLabel (pset.get< std::string >("OpFlashModuleLabel") ),
4018  fExternalCounterModuleLabel (pset.get< std::string >("ExternalCounterModuleLabel") ),
4019  fMCShowerModuleLabel (pset.get< std::string >("MCShowerModuleLabel") ),
4020  fMCTrackModuleLabel (pset.get< std::string >("MCTrackModuleLabel") ),
4021  fTrackModuleLabel (pset.get< std::vector<std::string> >("TrackModuleLabel")),
4022  fVertexModuleLabel (pset.get< std::vector<std::string> >("VertexModuleLabel")),
4023  fShowerModuleLabel (pset.get< std::vector<std::string> >("ShowerModuleLabel")),
4024  fCalorimetryModuleLabel (pset.get< std::vector<std::string> >("CalorimetryModuleLabel")),
4025  fParticleIDModuleLabel (pset.get< std::vector<std::string> >("ParticleIDModuleLabel") ),
4026  fMVAPIDShowerModuleLabel (pset.get< std::vector<std::string> >("MVAPIDShowerModuleLabel") ),
4027  fMVAPIDTrackModuleLabel (pset.get< std::vector<std::string> >("MVAPIDTrackModuleLabel") ),
4028  fFlashT0FinderLabel (pset.get< std::vector<std::string> >("FlashT0FinderLabel") ),
4029  fMCT0FinderLabel (pset.get< std::vector<std::string> >("MCT0FinderLabel") ),
4030  fPOTModuleLabel (pset.get< std::string >("POTModuleLabel")),
4031  fCosmicClusterTaggerAssocLabel (pset.get< std::string >("CosmicClusterTaggerAssocLabel")),
4032  fIsMC (pset.get< bool >("IsMC", false)),
4033  fUseBuffer (pset.get< bool >("UseBuffers", false)),
4034  fSaveAuxDetInfo (pset.get< bool >("SaveAuxDetInfo", false)),
4035  fSaveCryInfo (pset.get< bool >("SaveCryInfo", false)),
4036  fSaveGenieInfo (pset.get< bool >("SaveGenieInfo", false)),
4037  fSaveProtoInfo (pset.get< bool >("SaveProtoInfo", false)),
4038  fSavePhotonInfo (pset.get< bool >("SavePhotonInfo", false)),
4039  fSaveGeneratorInfo (pset.get< bool >("SaveGeneratorInfo", false)),
4040  fSaveGeantInfo (pset.get< bool >("SaveGeantInfo", false)),
4041  fSaveGeantInAVInfo (pset.get< bool >("SaveGeantInAVInfo", false)),
4042  fSaveGeantTrajectoryInfo (pset.get< bool >("SaveGeantTrajectoryInfo", false)),
4043  fSaveSimEnergyDepositTPCActiveInfo (pset.get< bool >("SaveSimEnergyDepositTPCActiveInfo", false)),
4044  fSaveMCShowerInfo (pset.get< bool >("SaveMCShowerInfo", false)),
4045  fSaveMCTrackInfo (pset.get< bool >("SaveMCTrackInfo", false)),
4046  fSaveHitInfo (pset.get< bool >("SaveHitInfo", false)),
4047  fSaveRawDigitInfo (pset.get< bool >("SaveRawDigitInfo", false)),
4048  fSaveRecobWireInfo (pset.get< bool >("SaveRecobWireInfo", false)),
4049  fSaveTrackInfo (pset.get< bool >("SaveTrackInfo", false)),
4050  fSaveVertexInfo (pset.get< bool >("SaveVertexInfo", false)),
4051  fSaveClusterInfo (pset.get< bool >("SaveClusterInfo", false)),
4052  fSavePandoraNuVertexInfo (pset.get< bool >("SavePandoraNuVertexInfo", false)),
4053  fSaveFlashInfo (pset.get< bool >("SaveFlashInfo", false)),
4054  fSaveExternCounterInfo (pset.get< bool >("SaveExternCounterInfo", false)),
4055  fSaveShowerInfo (pset.get< bool >("SaveShowerInfo", false)),
4056  fSavePFParticleInfo (pset.get< bool >("SavePFParticleInfo", false)),
4057  fCosmicTaggerAssocLabel (pset.get<std::vector< std::string > >("CosmicTaggerAssocLabel") ),
4058  fContainmentTaggerAssocLabel (pset.get<std::vector< std::string > >("ContainmentTaggerAssocLabel") ),
4059  fFlashMatchAssocLabel (pset.get<std::vector< std::string > >("FlashMatchAssocLabel") ),
4060  bIgnoreMissingShowers (pset.get< bool >("IgnoreMissingShowers", false)),
4061  isCosmics(false),
4062  fSaveCaloCosmics (pset.get< bool >("SaveCaloCosmics",false)),
4063  fG4minE (pset.get< float>("G4minE",0.01)),
4064  fMCSFitter( pset.get<fhicl::ParameterSet>("TrajMCSFitter") )
4065 
4066 {
4067 
4068  if (fSavePFParticleInfo) fPFParticleModuleLabel = pset.get<std::string>("PFParticleModuleLabel");
4069 
4070  if (fSaveAuxDetInfo == true) fSaveGeantInfo = true;
4071 // if (fSaveRawDigitInfo == true) fSaveHitInfo = true;
4072  mf::LogInfo("AnaRootParser") << "Configuration:"
4073  << "\n UseBuffers: " << std::boolalpha << fUseBuffer
4074  ;
4075  if (GetNTrackers() > kMaxTrackers) {
4077  << "AnaRootParser currently supports only up to " << kMaxTrackers
4078  << " tracking algorithms, but " << GetNTrackers() << " are specified."
4079  << "\nYou can increase kMaxTrackers and recompile.";
4080  } // if too many trackers
4081  if (fTrackModuleLabel.size() != fCalorimetryModuleLabel.size()){
4083  << "fTrackModuleLabel.size() = "<<fTrackModuleLabel.size()<<" does not match "
4084  << "fCalorimetryModuleLabel.size() = "<<fCalorimetryModuleLabel.size();
4085  }
4086  if (fTrackModuleLabel.size() != fParticleIDModuleLabel.size()){
4088  << "fTrackModuleLabel.size() = "<<fTrackModuleLabel.size()<<" does not match "
4089  << "fParticleIDModuleLabel.size() = "<<fParticleIDModuleLabel.size();
4090  }
4091  if (fTrackModuleLabel.size() != fFlashT0FinderLabel.size()){
4093  << "fTrackModuleLabel.size() = "<<fTrackModuleLabel.size()<<" does not match "
4094  << "fFlashT0FinderLabel.size() = "<<fFlashT0FinderLabel.size();
4095  }
4096  if (fTrackModuleLabel.size() != fMCT0FinderLabel.size()){
4098  << "fTrackModuleLabel.size() = "<<fTrackModuleLabel.size()<<" does not match "
4099  << "fMCT0FinderLabel.size() = "<<fMCT0FinderLabel.size();
4100  }
4101  if (fTrackModuleLabel.size() != fCosmicTaggerAssocLabel.size()) {
4103  << "fTrackModuleLabel.size() = "<<fTrackModuleLabel.size()<<" does not match "
4104  << "fCosmicTaggerAssocLabel.size() = "<<fCosmicTaggerAssocLabel.size();
4105  }
4106  if (fTrackModuleLabel.size() != fContainmentTaggerAssocLabel.size()) {
4108  << "fTrackModuleLabel.size() = "<<fTrackModuleLabel.size()<<" does not match "
4109  << "fCosmicTaggerAssocLabel.size() = "<<fContainmentTaggerAssocLabel.size();
4110  }
4111  if (fTrackModuleLabel.size() != fFlashMatchAssocLabel.size()) {
4113  << "fTrackModuleLabel.size() = "<<fTrackModuleLabel.size()<<" does not match "
4114  << "fCosmicTaggerAssocLabel.size() = "<<fFlashMatchAssocLabel.size();
4115  }
4116  if (GetNVertexAlgos() > kMaxVertexAlgos) {
4118  << "AnaRootParser currently supports only up to " << kMaxVertexAlgos
4119  << " tracking algorithms, but " << GetNVertexAlgos() << " are specified."
4120  << "\nYou can increase kMaxVertexAlgos and recompile.";
4121  } // if too many trackers
4122 
4123  // Build my Cryostat boundaries array...Taken from Tyler Alion in Geometry Core. Should still return the same values for uBoone.
4124  ActiveBounds[0] = ActiveBounds[2] = ActiveBounds[4] = DBL_MAX;
4125  ActiveBounds[1] = ActiveBounds[3] = ActiveBounds[5] = -DBL_MAX;
4126  // assume single cryostats
4127  auto const* geom = lar::providerFrom<geo::Geometry>();
4128  for (geo::TPCGeo const& TPC: geom->IterateTPCs()) {
4129  // get center in world coordinates
4130  double origin[3] = {0.};
4131  double center[3] = {0.};
4132  TPC.LocalToWorld(origin, center);
4133  double tpcDim[3] = {TPC.HalfWidth(), TPC.HalfHeight(), 0.5*TPC.Length() };
4134 
4135  if( center[0] - tpcDim[0] < ActiveBounds[0] ) ActiveBounds[0] = center[0] - tpcDim[0];
4136  if( center[0] + tpcDim[0] > ActiveBounds[1] ) ActiveBounds[1] = center[0] + tpcDim[0];
4137  if( center[1] - tpcDim[1] < ActiveBounds[2] ) ActiveBounds[2] = center[1] - tpcDim[1];
4138  if( center[1] + tpcDim[1] > ActiveBounds[3] ) ActiveBounds[3] = center[1] + tpcDim[1];
4139  if( center[2] - tpcDim[2] < ActiveBounds[4] ) ActiveBounds[4] = center[2] - tpcDim[2];
4140  if( center[2] + tpcDim[2] > ActiveBounds[5] ) ActiveBounds[5] = center[2] + tpcDim[2];
4141  } // for all TPC
4142  std::cout << "Active Boundaries: "
4143  << "\n\tx: " << ActiveBounds[0] << " to " << ActiveBounds[1]
4144  << "\n\ty: " << ActiveBounds[2] << " to " << ActiveBounds[3]
4145  << "\n\tz: " << ActiveBounds[4] << " to " << ActiveBounds[5]
4146  << std::endl;
4147 } // dune::AnaRootParser::AnaRootParser()
4148 
4149 //-------------------------------------------------
4151 {
4152  DestroyData();
4153 }
4154 
4155 void dune::AnaRootParser::CreateTree(bool bClearData /* = false */) {
4156  if (!fTree) {
4158  fTree = tfs->make<TTree>("anatree","analysis tree");
4159  }
4160  /* if (!fPOT) {
4161  art::ServiceHandle<art::TFileService> tfs;
4162  fPOT = tfs->make<TTree>("pottree","pot tree");
4163  fPOT->Branch("pot",&SubRunData.pot,"pot/D");
4164  fPOT->Branch("potbnbETOR860",&SubRunData.potbnbETOR860,"potbnbETOR860/D");
4165  fPOT->Branch("potbnbETOR875",&SubRunData.potbnbETOR875,"potbnbETOR875/D");
4166  fPOT->Branch("potnumiETORTGT",&SubRunData.potnumiETORTGT,"potnumiETORTGT/D");
4167  }*/
4168  CreateData(bClearData);
4169  SetAddresses();
4170 } // dune::AnaRootParser::CreateTree()
4171 
4172 
4174 {
4175 
4176  // auto potListHandle = sr.getHandle< sumdata::POTSummary >(fPOTModuleLabel);
4177  // if(potListHandle)
4178  // SubRunData.pot=potListHandle->totpot;
4179  // else
4180  // SubRunData.pot=0.;
4181 
4182 }
4183 
4185 {
4186 
4187  /* auto potListHandle = sr.getHandle< sumdata::POTSummary >(fPOTModuleLabel);
4188  if (potListHandle)
4189  SubRunData.pot=potListHandle->totpot;
4190  else
4191  SubRunData.pot=0.;
4192 
4193  art::InputTag itag1("beamdata","bnbETOR860");
4194  auto potSummaryHandlebnbETOR860 = sr.getHandle<sumdata::POTSummary>(itag1);
4195  if (potSummaryHandlebnbETOR860){
4196  SubRunData.potbnbETOR860 = potSummaryHandlebnbETOR860->totpot;
4197  }
4198  else
4199  SubRunData.potbnbETOR860 = 0;
4200 
4201  art::InputTag itag2("beamdata","bnbETOR875");
4202  auto potSummaryHandlebnbETOR875 = sr.getHandle<sumdata::POTSummary>(itag2);
4203  if (potSummaryHandlebnbETOR875){
4204  SubRunData.potbnbETOR875 = potSummaryHandlebnbETOR875->totpot;
4205  }
4206  else
4207  SubRunData.potbnbETOR875 = 0;
4208 
4209  art::InputTag itag3("beamdata","numiETORTGT");
4210  auto potSummaryHandlenumiETORTGT = sr.getHandle<sumdata::POTSummary>(itag3);
4211  if (potSummaryHandlenumiETORTGT){
4212  SubRunData.potnumiETORTGT = potSummaryHandlenumiETORTGT->totpot;
4213  }
4214  else
4215  SubRunData.potnumiETORTGT = 0;
4216 
4217  if (fPOT) fPOT->Fill();
4218  */
4219 }
4220 
4222 {
4223 
4224  //services
4225 // art::ServiceHandle<cheat::BackTrackerService> bt_serv;
4227 
4228  // collect the sizes which might be needed to resize the tree data structure:
4229 
4230  // RawDigit
4231  std::vector<art::Ptr<raw::RawDigit> > rawdigitlist;
4232  auto rawdigitVecHandle = evt.getHandle< std::vector<raw::RawDigit> >(fRawDigitModuleLabel);
4233  if (rawdigitVecHandle)
4234  art::fill_ptr_vector(rawdigitlist, rawdigitVecHandle);
4235 
4236  // RecobWire
4237  std::vector<art::Ptr<recob::Wire> > recobwirelist;
4238  auto recobwireVecHandle = evt.getHandle< std::vector<recob::Wire> >(fCalDataModuleLabel);
4239  if (recobwireVecHandle)
4240  art::fill_ptr_vector(recobwirelist, recobwireVecHandle);
4241 
4242 
4243  // recob::Wire
4244 // auto wireVecHandle = evt.getHandle< std::vector<recob::Wire> >(fCalDataModuleLabel);
4245 
4246  // * photons
4247  //std::vector<art::Ptr<sim::SimPhotonsLite> > photonlist;
4249  if(fSavePhotonInfo) photonHandle = evt.getHandle< std::vector<sim::SimPhotonsLite> >(fPhotonPropS1ModuleLabel);
4250 // art::fill_ptr_vector(photonlist, photonHandle);
4251 
4252  // * hits
4253  std::vector<art::Ptr<recob::Hit> > hitlist;
4254  auto hitListHandle = evt.getHandle< std::vector<recob::Hit> >(fHitsModuleLabel);
4255  if (hitListHandle)
4256  art::fill_ptr_vector(hitlist, hitListHandle);
4257 
4258  // * clusters
4259  art::Handle< std::vector<recob::Cluster> > clusterListHandle;
4260  std::vector<art::Ptr<recob::Cluster> > clusterlist;
4261  if (fSaveClusterInfo){
4262  clusterListHandle = evt.getHandle< std::vector<recob::Cluster> >(fClusterModuleLabel);
4263  if (clusterListHandle)
4264  art::fill_ptr_vector(clusterlist, clusterListHandle);
4265  }
4266 
4267  // * flashes
4268  std::vector<art::Ptr<recob::OpFlash> > flashlist;
4269  auto flashListHandle = evt.getHandle< std::vector<recob::OpFlash> >(fOpFlashModuleLabel);
4270  if (flashListHandle)
4271  art::fill_ptr_vector(flashlist, flashListHandle);
4272 
4273  // * External Counters
4274  std::vector<art::Ptr<raw::ExternalTrigger> > countlist;
4275  auto countListHandle = evt.getHandle< std::vector<raw::ExternalTrigger> >(fExternalCounterModuleLabel);
4276  if (countListHandle)
4277  art::fill_ptr_vector(countlist, countListHandle);
4278 
4279  // * MC truth information
4280  art::Handle< std::vector<simb::MCTruth> > mctruthListHandle;
4281  std::vector<art::Ptr<simb::MCTruth> > mclist;
4282  if (fIsMC){
4283  mctruthListHandle = evt.getHandle< std::vector<simb::MCTruth> >(fGenieGenModuleLabel);
4284  if (mctruthListHandle)
4285  art::fill_ptr_vector(mclist, mctruthListHandle);
4286  }
4287 
4288  // SimEnergyDepositTPCActive
4289  int nSimEnergyDepositsTPCActive = 0;
4290  int nParticlesWithSimEnergyDepositsTPCActive = 0;
4291  int nLowestParticleIDSimEnergyDepositsTPCActive = 0;
4292  int nHighestParticleIDSimEnergyDepositsTPCActive = 0;
4293 
4294  std::vector<art::Ptr<sim::SimEnergyDeposit> > energyDepositTPCActivelist;
4296  {
4297  auto energyDepositTPCActiveHandle = evt.getHandle< std::vector<sim::SimEnergyDeposit> >(fSimEnergyDepositTPCActiveLabel);
4298  if (energyDepositTPCActiveHandle)
4299  {
4300  art::fill_ptr_vector(energyDepositTPCActivelist,energyDepositTPCActiveHandle);
4301  nSimEnergyDepositsTPCActive = energyDepositTPCActivelist.size();
4302 
4303  std::vector<int> tempparticleID;
4304  tempparticleID.resize(nSimEnergyDepositsTPCActive);
4305  FillWith(tempparticleID, 0);
4306 
4307  for(int sedavit = 0; sedavit < nSimEnergyDepositsTPCActive; sedavit++)
4308  {
4309  if( std::find(tempparticleID.begin(), tempparticleID.end(), energyDepositTPCActivelist[sedavit]->TrackID()) == tempparticleID.end() ) //check if current particle ID is already in the vector. if true: not in vector
4310  {
4311  tempparticleID[nParticlesWithSimEnergyDepositsTPCActive] = energyDepositTPCActivelist[sedavit]->TrackID();
4312  nParticlesWithSimEnergyDepositsTPCActive++;
4313  }
4314  if(energyDepositTPCActivelist[sedavit]->TrackID() < nLowestParticleIDSimEnergyDepositsTPCActive) nLowestParticleIDSimEnergyDepositsTPCActive=energyDepositTPCActivelist[sedavit]->TrackID();
4315  if(energyDepositTPCActivelist[sedavit]->TrackID() > nHighestParticleIDSimEnergyDepositsTPCActive) nHighestParticleIDSimEnergyDepositsTPCActive=energyDepositTPCActivelist[sedavit]->TrackID();
4316  }
4317 
4318  }
4319  }
4320 
4321  // *MC truth cosmic generator information
4322  std::vector<art::Ptr<simb::MCTruth> > mclistcry;
4323  if (fIsMC && fSaveCryInfo){
4324  auto mctruthcryListHandle = evt.getHandle< std::vector<simb::MCTruth> >(fCryGenModuleLabel);
4325  if (mctruthcryListHandle){
4326  art::fill_ptr_vector(mclistcry, mctruthcryListHandle);
4327  }
4328  else{
4329  // If we requested this info but it doesn't exist, don't use it.
4330  fSaveCryInfo = false;
4331  mf::LogError("AnaRootParser") << "Requested CRY information but none exists, hence not saving CRY information.";
4332  }
4333  }
4334 
4335  // ProtoDUNE beam generator information
4336  std::vector<art::Ptr<simb::MCTruth> > mclistproto;
4337  if(fIsMC && fSaveProtoInfo){
4338  auto mctruthprotoListHandle = evt.getHandle< std::vector<simb::MCTruth> >(fProtoGenModuleLabel);
4339  if (mctruthprotoListHandle){
4340  art::fill_ptr_vector(mclistproto,mctruthprotoListHandle);
4341  }
4342  else{
4343  // If we requested this info but it doesn't exist, don't use it.
4344  fSaveProtoInfo = false;
4345  mf::LogError("AnaRootParser") << "Requested protoDUNE beam generator information but none exists, hence not saving protoDUNE beam generator information.";
4346  }
4347  }
4348 
4349  // *MC Shower information
4351  if (fIsMC)
4352  mcshowerh = evt.getHandle< std::vector<sim::MCShower> >(fMCShowerModuleLabel);
4353 
4354  int nMCShowers = 0;
4355  if (fSaveMCShowerInfo && mcshowerh.isValid())
4356  nMCShowers = mcshowerh->size();
4357 
4358  // *MC Track information
4360  if (fIsMC)
4361  mctrackh = evt.getHandle< std::vector<sim::MCTrack> >(fMCTrackModuleLabel);
4362 
4363  int nMCTracks = 0;
4364  if (fSaveMCTrackInfo && mctrackh.isValid())
4365  nMCTracks = mctrackh->size();
4366 
4367  art::Ptr<simb::MCTruth> mctruthcry;
4368  int nCryPrimaries = 0;
4369 
4370  if (fSaveCryInfo){
4371  mctruthcry = mclistcry[0];
4372  nCryPrimaries = mctruthcry->NParticles();
4373  }
4374 
4375  art::Ptr<simb::MCTruth> mctruthproto;
4376  int nProtoPrimaries = 0;
4377  if( fSaveProtoInfo){
4378  mctruthproto = mclistproto[0];
4379  nProtoPrimaries = mctruthproto->NParticles();
4380  }
4381 
4382  int nPhotons=0;
4383  int nGeniePrimaries = 0, nGeneratorParticles = 0, nGEANTparticles = 0, nGEANTparticlesInAV = 0, nGEANTtrajectorysteps=0;
4384 
4385  art::Ptr<simb::MCTruth> mctruth;
4386 
4387 
4388  if (fIsMC) { //is MC
4389 
4390  //find origin
4391  auto const allmclists = evt.getMany<std::vector<simb::MCTruth>>();
4392  for(size_t mcl = 0; mcl < allmclists.size(); ++mcl){
4393  art::Handle< std::vector<simb::MCTruth> > mclistHandle = allmclists[mcl];
4394  for(size_t m = 0; m < mclistHandle->size(); ++m){
4395  art::Ptr<simb::MCTruth> mct(mclistHandle, m);
4396  if (mct->Origin() == simb::kCosmicRay) isCosmics = true;
4397  }
4398  }
4399  if (fSaveCaloCosmics) isCosmics = false; //override to save calo info
4400 
4401  // GENIE
4402  if (!mclist.empty()){//at least one mc record
4403 
4404  // double maxenergy = -1;
4405  // int imc0 = 0;
4406  // for (std::map<art::Ptr<simb::MCTruth>,double>::iterator ii=mctruthemap.begin(); ii!=mctruthemap.end(); ++ii){
4407  // if ((ii->second)>maxenergy){
4408  // maxenergy = ii->second;
4409  // mctruth = ii->first;
4410  // imc = imc0;
4411  // }
4412  // imc0++;
4413  // }
4414 
4415  //imc = 0; //set imc to 0 to solve a confusion for BNB+cosmic files where there are two MCTruth
4416  mctruth = mclist[0];
4417 
4418  if (mctruth->NeutrinoSet()) nGeniePrimaries = mctruth->NParticles();
4419  //} //end (fSaveGenieInfo)
4420 
4421  const sim::ParticleList& plist = pi_serv->ParticleList();
4422  nGEANTparticles = plist.size();
4423 
4424  sim::ParticleList::const_iterator itPart = plist.begin(),
4425  pend = plist.end(); // iterator to pairs (track id, particle)
4426 
4427  std::string pri("primary");
4428  for(size_t iPart = 0; (iPart < plist.size()) && (itPart != pend); ++iPart)
4429  {
4430  const simb::MCParticle* pPart = (itPart++)->second;
4431  if (!pPart)
4432  {
4434  << "GEANT particle #" << iPart << " returned a null pointer";
4435  }
4436  nGEANTtrajectorysteps += pPart->NumberTrajectoryPoints();
4437 
4438  if(pPart->Mother() == 0 && pPart->Process() == pri) nGeneratorParticles++;
4439 
4440  TLorentzVector mcstart, mcend;
4441  unsigned int pstarti, pendi;
4442  double plen = length(*pPart, mcstart, mcend, pstarti, pendi);
4443  if( plen != 0) nGEANTparticlesInAV += 1;
4444 
4445  } // for particles
4446 
4447  // counting photons
4448  if(fSavePhotonInfo)
4449  {
4450  for ( auto const& pmt : (*photonHandle) )
4451  {
4452  std::map<int, int> PhotonsMap = pmt.DetectedPhotons;
4453 
4454  for(auto itphoton = PhotonsMap.begin(); itphoton!= PhotonsMap.end(); itphoton++)
4455  {
4456  for(int i = 0; i < itphoton->second ; i++)
4457  {
4458  nPhotons++;
4459  }
4460  }
4461  }
4462  }
4463  } // if have MC truth
4464  MF_LOG_DEBUG("AnaRootParser") << "Expected "
4465  << nGEANTparticles << " GEANT particles, "
4466  << nGeniePrimaries << " GENIE particles";
4467  } // if MC
4468 
4469 CreateData(); // tracker data is created with default constructor
4470 if (fSaveGenieInfo){ fData->ResizeGenie(nGeniePrimaries);}
4471 if (fSaveCryInfo){ fData->ResizeCry(nCryPrimaries);}
4472 if (fSaveProtoInfo){ fData->ResizeProto(nProtoPrimaries);}
4473 if (fSaveGeneratorInfo){ fData->ResizeGenerator(nGeneratorParticles);}
4474 if (fSaveGeantInfo){ fData->ResizeGEANT(nGEANTparticles);}
4475 if (fSaveGeantInfo && fSaveGeantInAVInfo){ fData->ResizeGEANTInAV(nGEANTparticlesInAV);}
4476 if (fSaveGeantTrajectoryInfo){ fData->ResizeGEANTTrajectory(nGEANTtrajectorysteps);}
4477 if (fSaveSimEnergyDepositTPCActiveInfo) {fData->ResizeSimEnergyDepositsTPCActive(nSimEnergyDepositsTPCActive, nParticlesWithSimEnergyDepositsTPCActive);}
4478 if (fSaveMCShowerInfo){ fData->ResizeMCShower(nMCShowers);}
4479 if (fSaveMCTrackInfo){ fData->ResizeMCTrack(nMCTracks);}
4480 if (fSavePhotonInfo){ fData->ResizePhotons(nPhotons);}
4481 
4482 if(fLogLevel >= 1)
4483 {
4484  std::cout << "nGeneratorParticles: " << nGeneratorParticles << std::endl;
4485  std::cout << "nGEANTparticles: " << nGEANTparticles << std::endl;
4486  std::cout << "nGEANTtrajectorysteps: " << nGEANTtrajectorysteps << std::endl;
4487  std::cout << "nGEANTparticlesInAV: " << nGEANTparticlesInAV << std::endl;
4488  std::cout << "nSimEnergyDepositsTPCActive: " << nSimEnergyDepositsTPCActive << std::endl;
4489  std::cout << "nParticlesWithSimEnergyDepositsTPCActive: " << nParticlesWithSimEnergyDepositsTPCActive << std::endl;
4490  std::cout << "nLowestParticleIDSimEnergyDepositsTPCActive: " << nLowestParticleIDSimEnergyDepositsTPCActive << std::endl;
4491  std::cout << "nHighestParticleIDSimEnergyDepositsTPCActive: " << nHighestParticleIDSimEnergyDepositsTPCActive << std::endl;
4492  std::cout << "nPhotons: " << nPhotons << std::endl;
4493 }
4494 
4495  fData->ClearLocalData(); // don't bother clearing tracker data yet
4496 
4497  const size_t NTrackers = GetNTrackers(); // number of trackers passed into fTrackModuleLabel
4498  const size_t NShowerAlgos = GetNShowerAlgos(); // number of shower algorithms into fShowerModuleLabel
4499  const size_t NChannels = rawdigitlist.size(); //number of channels holding raw waveforms
4500  const size_t NRecoChannels = recobwirelist.size(); //number of channels holding ROI's
4501  const size_t NHits = hitlist.size(); // number of hits
4502  const size_t NVertexAlgos = GetNVertexAlgos(); // number of vertex algos
4503  const size_t NClusters = clusterlist.size(); //number of clusters
4504  const size_t NFlashes = flashlist.size(); // number of flashes
4505  const size_t NExternCounts = countlist.size(); // number of External Counters
4506  // make sure there is the data, the tree and everything;
4507  CreateTree();
4508 
4509  /// transfer the run and subrun data to the tree data object
4510  // fData->RunData = RunData;
4511  fData->SubRunData = SubRunData;
4512 
4513  fData->isdata = int(!fIsMC);
4514 
4515  // raw trigger
4516  std::vector<art::Ptr<raw::Trigger> > triggerlist;
4517  auto triggerListHandle = evt.getHandle< std::vector<raw::Trigger>>(fRawDigitModuleLabel);
4518  if (triggerListHandle){ art::fill_ptr_vector(triggerlist, triggerListHandle);}
4519 
4520  if (triggerlist.size()){
4521  fData->triggernumber = triggerlist[0]->TriggerNumber();
4522  fData->triggertime = triggerlist[0]->TriggerTime();
4523  fData->beamgatetime = triggerlist[0]->BeamGateTime();
4524  fData->triggerbits = triggerlist[0]->TriggerBits();
4525  }
4526 
4527 // vertices
4528  std::vector< art::Handle< std::vector<recob::Vertex> > > vertexListHandle(NVertexAlgos);
4529  std::vector< std::vector<art::Ptr<recob::Vertex> > > vertexlist(NVertexAlgos);
4530  for (unsigned int it = 0; it < NVertexAlgos; ++it){
4531  vertexListHandle[it] = evt.getHandle< std::vector<recob::Vertex> >(fVertexModuleLabel[it]);
4532  if (vertexListHandle[it])
4533  art::fill_ptr_vector(vertexlist[it], vertexListHandle[it]);
4534 }
4535 
4536 // PFParticles
4537 lar_pandora::PFParticleVector pfparticlelist;
4538 lar_pandora::PFParticlesToClusters pfParticleToClusterMap;
4539 lar_pandora::LArPandoraHelper::CollectPFParticles(evt, fPFParticleModuleLabel, pfparticlelist, pfParticleToClusterMap);
4540 
4541 // tracks
4542 std::vector< art::Handle< std::vector<recob::Track> > > trackListHandle(NTrackers);
4543 std::vector< std::vector<art::Ptr<recob::Track> > > tracklist(NTrackers);
4544 for (unsigned int it = 0; it < NTrackers; ++it){
4545  trackListHandle[it] = evt.getHandle< std::vector<recob::Track> >(fTrackModuleLabel[it]);
4546  if (trackListHandle[it])
4547  art::fill_ptr_vector(tracklist[it], trackListHandle[it]);
4548 }
4549 
4550 // showers
4551 // It seems that sometimes the shower data product does not exist;
4552 // in that case, we store a nullptr in place of the pointer to the vector;
4553 // the data structure itself is owned by art::Event and we should not try
4554 // to manage its memory
4555 std::vector<std::vector<recob::Shower> const*> showerList;
4556 std::vector< art::Handle< std::vector<recob::Shower> > > showerListHandle;
4557 showerList.reserve(fShowerModuleLabel.size());
4558 if (fSaveShowerInfo) {
4559  for (art::InputTag ShowerInputTag: fShowerModuleLabel) {
4560  auto ShowerHandle = evt.getHandle<std::vector<recob::Shower>>(ShowerInputTag);
4561  if (!ShowerHandle) {
4562  showerList.push_back(nullptr);
4563  if (!bIgnoreMissingShowers) {
4565  << "Showers with input tag '" << ShowerInputTag.encode()
4566  << "' were not found in the event."
4567  " If you really know what you are doing,"
4568  " set AnaRootParser's configuration parameter IgnoreMissingShowers"
4569  " to \"true\"; the lack of any shower set will be tolerated,"
4570  " and the shower list in the corresponding event will be set to"
4571  " a list of one shower, with an invalid ID.\n";
4572  } // if bIgnoreMissingShowers
4573  else {
4574  // this message is more alarming than strictly necessary; by design.
4575  mf::LogError("AnaRootParser")
4576  << "No showers found for input tag '" << ShowerInputTag.encode()
4577  << "' ; FILLING WITH FAKE DATA AS FOR USER'S REQUEST";
4578  }
4579  }
4580 
4581  else showerList.push_back(ShowerHandle.product());
4582 
4583  showerListHandle.push_back(ShowerHandle); // either way, put it into the handle list
4584 
4585  }
4586 
4587 } // for shower input tag
4588 
4589 
4590 // Find the simb::MCFlux objects corresponding to
4591 // each simb::MCTruth object made by the generator with
4592 // the label fGenieGenModuleLabel
4593 // art::FindOne<simb::MCFlux> find_mcflux(mctruthListHandle, evt, fGenieGenModuleLabel);
4594 
4595 std::vector<const sim::AuxDetSimChannel*> fAuxDetSimChannels;
4596 if (fSaveAuxDetInfo){
4597  evt.getView(fElecDriftModuleLabel, fAuxDetSimChannels);
4598 }
4599 
4600 std::vector<const sim::SimChannel*> fSimChannels;
4601 if (fIsMC && fSaveGeantInfo){ evt.getView(fElecDriftModuleLabel, fSimChannels);}
4602 
4603  fData->run = evt.run();
4604  fData->subrun = evt.subRun();
4605  fData->event = evt.id().event() + fEventsPerSubrun*evt.subRun();
4606 
4607  art::Timestamp ts = evt.time();
4608  fData->evttime_seconds = ts.timeHigh();
4609  fData->evttime_nanoseconds = ts.timeLow();
4610 
4611  //copied from MergeDataPaddles.cxx
4612  auto beam = evt.getHandle< raw::BeamInfo >("beamdata");
4613  if (beam){
4614  fData->beamtime = (double)beam->get_t_ms();
4615  fData->beamtime/=1000.; //in second
4616  std::map<std::string, std::vector<double>> datamap = beam->GetDataMap();
4617  if (datamap["E:TOR860"].size()){
4618  fData->potbnb = datamap["E:TOR860"][0];
4619  }
4620  if (datamap["E:TORTGT"].size()){
4621  fData->potnumitgt = datamap["E:TORTGT"][0];
4622  }
4623  if (datamap["E:TOR101"].size()){
4624  fData->potnumi101 = datamap["E:TOR101"][0];
4625  }
4626  }
4627 
4628  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
4629  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt, clockData);
4630 // std::cout<<detProp.NumberTimeSamples()<<" "<<detProp.ReadOutWindowSize()<<std::endl;
4631 // std::cout<<geom->DetHalfHeight()2<<" "<<geom->DetHalfWidth()2<<" "<<geom->DetLength()<<std::endl;
4632 // std::cout<<geom->Nwires(0)<<" "<<geom->Nwires(1)<<" "<<geom->Nwires(2)<<std::endl;
4633 
4634 
4635 //RawDigit info
4636 if (fSaveRawDigitInfo){
4637  fData->no_channels = (int) NChannels;
4638  if (NChannels>0)
4639  {
4640  fData->no_ticks = (int) rawdigitlist[0]->Samples();
4641  fData->no_ticksinallchannels = fData->no_channels*fData->no_ticks;
4642  }
4643  else
4644  {
4645  fData->no_ticks = 0;
4646  fData->no_ticksinallchannels = 0;
4647  }
4648 
4649  for (int i = 0; i < fData->no_channels ; i++) //loop over channels holding raw waveforms
4650  {
4651  fData->rawD_Channel[i] = (int) rawdigitlist[i]->Channel();
4652  int k=0;
4653 
4654  for (int j = fData->no_ticks*i; j < (fData->no_ticks*(i+1)) && j < kMaxReadoutTicksInAllChannels ; j++) //loop over ticks
4655  {
4656  fData->rawD_ADC[j] = rawdigitlist[i]->ADC(k);
4657  k++;
4658  }
4659  }
4660 }
4661 
4662 //RecobWire info
4663 if (fSaveRecobWireInfo){
4664  fData->no_recochannels = (int) NRecoChannels;
4665  int RecoWTick=0;
4666 
4667  for(int i = 0; i < fData->no_recochannels; i++) //loop over channels holding reco waveforms
4668  {
4669  fData->recoW_NTicks[i]=0;
4670  fData->recoW_Channel[i] = recobwirelist[i]->Channel();
4671  const recob::Wire::RegionsOfInterest_t& signalROI = recobwirelist[i]->SignalROI();
4672 
4673  for(const auto& range : signalROI.get_ranges()) //loop over ROIs
4674  {
4675  const std::vector<float>& signal = range.data();
4676  int NTicksInThisROI = range.end_index() - range.begin_index();
4677 
4678  for(int j = 0; j < NTicksInThisROI; j++) //loop over ticks
4679  {
4680  fData->recoW_Tick[RecoWTick] = j+range.begin_index();
4681  fData->recoW_ADC[RecoWTick] = signal.at(j);
4682  RecoWTick++;
4683  }
4684  fData->recoW_NTicks[i] += NTicksInThisROI;
4685  }
4686  }
4687  fData->no_recoticksinallchannels = RecoWTick;
4688 }
4689 
4690 //hit information
4691 if (fSaveHitInfo){
4692 
4693  int trueID = -9999;
4694  float maxe = -9999;
4695  float purity = -9999;
4696 
4697  fData->no_hits = (int) NHits;
4698  fData->NHitsInAllTracks = (int) NHits;
4699  fData->no_hits_stored = TMath::Min( (int) NHits, (int) kMaxHits);
4700  if (NHits > kMaxHits) {
4701  // got this error? consider increasing kMaxHits
4702  // (or ask for a redesign using vectors)
4703  mf::LogError("AnaRootParser:limits") << "event has " << NHits
4704  << " hits, only kMaxHits=" << kMaxHits << " stored in tree";
4705  }
4706 
4707 // trying to assign a space point to those recob::Hits t hat were assigned to a track, checking for every hit. Not really working yet.
4708 // art::FindManyP<recob::SpacePoint> fmsp(hitlist,evt,"pmtrack");
4709 
4710  auto hitResults = anab::FVectorReader<recob::Hit, 4>::create(evt, "dprawhit");
4711  const auto & fitParams = hitResults->vectors();
4712 
4713  for (size_t i = 0; i < NHits && i < kMaxHits ; ++i){//loop over hits
4714  fData->hit_channel[i] = hitlist[i]->Channel();
4715  fData->hit_tpc[i] = hitlist[i]->WireID().TPC;
4716  fData->hit_view[i] = hitlist[i]->WireID().Plane;
4717  fData->hit_wire[i] = hitlist[i]->WireID().Wire;
4718  fData->hit_peakT[i] = hitlist[i]->PeakTime();
4719  fData->hit_chargesum[i] = hitlist[i]->SummedADC();
4720  fData->hit_chargeintegral[i] = hitlist[i]->Integral();
4721  fData->hit_ph[i] = hitlist[i]->PeakAmplitude();
4722  fData->hit_startT[i] = hitlist[i]->StartTick();
4723  fData->hit_endT[i] = hitlist[i]->EndTick();
4724  fData->hit_rms[i] = hitlist[i]->RMS();
4725  fData->hit_goodnessOfFit[i] = hitlist[i]->GoodnessOfFit();
4726 
4727  fData->hit_fitparamt0[i] = fitParams[i][0];
4728  fData->hit_fitparamtau1[i] = fitParams[i][1];
4729  fData->hit_fitparamtau2[i] = fitParams[i][2];
4730  fData->hit_fitparamampl[i] = fitParams[i][3];
4731 
4732  fData->hit_multiplicity[i] = hitlist[i]->Multiplicity();
4733 
4734  //quantities from backtracker are different from the real value in MC
4735 
4736  if( fIsMC )
4737  HitsBackTrack(clockData, hitlist[i], trueID, maxe, purity );
4738 
4739  fData->hit_trueID[i] = trueID;
4740  fData->hit_trueEnergyMax[i] = maxe;
4741  fData->hit_trueEnergyFraction[i] = purity;
4742 
4743 /*
4744  std::vector< art::Ptr<recob::SpacePoint> > sptv = fmsp.at(i);
4745  if (fmsp.at(i).size()!=0){
4746  std::cout << "sptv[i]->XYZ()[0]: " << sptv[i]->XYZ()[0] << std::endl;
4747  std::cout << "sptv[i]->XYZ()[1]: " << sptv[i]->XYZ()[1] << std::endl;
4748  std::cout << "sptv[i]->XYZ()[2]: " << sptv[i]->XYZ()[2] << std::endl;
4749  }
4750  std::cout << "test3" << std::endl;
4751 // std::cout << "test" << std::endl;
4752 // art::FindManyP<recob::SpacePoint> fmsp(hitListHandle,evt,"pmtrack");
4753 // art::FindManyP<recob::SpacePoint> fmsp(allHits, evt, fSpacePointModuleLabel);
4754 // art::FindManyP<recob::SpacePoint> fmsp(hitlist,evt,"pmtrack");
4755  for (size_t i = 0; i < NHits && i < kMaxHits ; ++i){//loop over hits
4756  if (fmsp.isValid()){
4757  if (fmsp.at(i).size()!=0){
4758 
4759  std::cout << "Spacepoint in x for hit" << i << ": " << fmsp.at(i)[0]->XYZ()[0] << std::endl;
4760  // fData->hit_clusterid[i] = fmcl.at(i)[0]->ID();
4761  // fData->hit_clusterKey[i] = fmcl.at(i)[0].key();
4762  }
4763  else std::cout << "No spacepoint for this hit" << std::endl;
4764  }
4765  }
4766  //Get space points associated with the hit
4767  std::vector< art::Ptr<recob::SpacePoint> > sptv = fmsp.at(hits[ipl][i]);
4768 */
4769 
4770 
4771 
4772  //std::vector<double> xyz = bt_serv->HitToXYZ(hitlist[i]);
4773  //when the size of simIDEs is zero, the above function throws an exception
4774  //and crashes, so check that the simIDEs have non-zero size before
4775  //extracting hit true XYZ from simIDEs
4776  // if (fIsMC){
4777  // std::vector<sim::IDE> ides;
4778  // try{bt_serv->HitToSimIDEs(hitlist[i], ides); }
4779  // catch(...){}
4780  // if (ides.size()>0){
4781  // std::vector<double> xyz = bt_serv->SimIDEsToXYZ(ides);
4782  // fData->hit_trueX[i] = xyz[0];
4783  // }
4784  // }
4785  /*
4786  for (unsigned int it=0; it<fTrackModuleLabel.size();++it){
4787  art::FindManyP<recob::Track> fmtk(hitListHandle,evt,fTrackModuleLabel[it]);
4788  if (fmtk.at(i).size()!=0){
4789  hit_trkid[it][i] = fmtk.at(i)[0]->ID();
4790  }
4791  else
4792  hit_trkid[it][i] = 0;
4793  }
4794  */
4795 
4796 /*
4797  if (fSaveRawDigitInfo){
4798  //Hit to RawDigit information
4799  art::FindManyP<raw::RawDigit> fmrd(hitListHandle,evt,fHitsModuleLabel);
4800  if (hitlist[i]->WireID().Plane==2)
4801  {
4802  int dataSize = fmrd.at(i)[0]->Samples();
4803  short ped = fmrd.at(i)[0]->GetPedestal();
4804 
4805  std::vector<short> rawadc(dataSize);
4806  raw::Uncompress(fmrd.at(i)[0]->ADCs(), rawadc, fmrd.at(i)[0]->Compression());
4807  int t0 = hitlist[i]->PeakTime() - 3*(hitlist[i]->RMS());
4808  if (t0<0) t0 = 0;
4809  int t1 = hitlist[i]->PeakTime() + 3*(hitlist[i]->RMS());
4810  if (t1>=dataSize) t1 = dataSize-1;
4811  fData->rawD_ph[i] = -1;
4812  fData->rawD_peakT[i] = -1;
4813  for (int j = t0; j<=t1; ++j){
4814  if (rawadc[j]-ped>fData->rawD_ph[i]){
4815  fData->rawD_ph[i] = rawadc[j]-ped;
4816  fData->rawD_peakT[i] = j;
4817  }
4818  }
4819  fData->rawD_charge[i] = 0;
4820  fData->rawD_fwhh[i] = 0;
4821  double mean_t = 0.0;
4822  double mean_t2 = 0.0;
4823  for (int j = t0; j<=t1; ++j){
4824  if (rawadc[j]-ped>=0.5*fData->rawD_ph[i]){
4825  ++fData->rawD_fwhh[i];
4826  }
4827  if (rawadc[j]-ped>=0.1*fData->rawD_ph[i]){
4828  fData->rawD_charge[i] += rawadc[j]-ped;
4829  mean_t += (double)j*(rawadc[j]-ped);
4830  mean_t2 += (double)j*(double)j*(rawadc[j]-ped);
4831  }
4832  }
4833  mean_t/=fData->rawD_charge[i];
4834  mean_t2/=fData->rawD_charge[i];
4835  fData->rawD_rms[i] = sqrt(mean_t2-mean_t*mean_t);
4836  }
4837  } // Save RawDigitInfo
4838 */
4839  /* if (!evt.isRealData()&&!isCosmics){
4840  fData -> hit_nelec[i] = 0;
4841  fData -> hit_energy[i] = 0;
4842  const sim::SimChannel* chan = 0;
4843  for(size_t sc = 0; sc < fSimChannels.size(); ++sc){
4844  if(fSimChannels[sc]->Channel() == hitlist[i]->Channel()) chan = fSimChannels[sc];
4845  }
4846  if (chan){
4847  for(auto const& mapitr : chan->TDCIDEMap()){
4848  // loop over the vector of IDE objects.
4849  for(auto const& ide : mapitr.second){
4850  fData -> hit_nelec[i] += ide.numElectrons;
4851  fData -> hit_energy[i] += ide.energy;
4852  }
4853  }
4854  }
4855  }*/
4856  } // Loop over hits
4857 
4858 
4859  hitListHandle = evt.getHandle< std::vector<recob::Hit> >(fHitsModuleLabel);
4860  if (hitListHandle){
4861  //Find tracks associated with hits
4862  art::FindManyP<recob::Track> fmtk(hitListHandle,evt,fTrackModuleLabel[0]);
4863  for (size_t i = 0; i < NHits && i < kMaxHits ; ++i){//loop over hits
4864  if (fmtk.isValid()){
4865  if (fmtk.at(i).size()!=0){
4866  fData->hit_trkid[i] = fmtk.at(i)[0]->ID();
4867  // fData->hit_trkKey[i] = fmtk.at(i)[0].key();
4868 
4869  }
4870  else
4871  fData->hit_trkid[i] = -1;
4872  }
4873  }
4874  }
4875 
4876  //In the case of ClusterCrawler or linecluster, use "linecluster or clustercrawler" as HitModuleLabel.
4877  //using cchit will not make this association. In the case of gaushit, just use gaushit
4878  //Not initializing clusterID to -1 since some clustering algorithms assign negative IDs!
4879  hitListHandle = evt.getHandle< std::vector<recob::Hit> >(fHitsModuleLabel);
4880  if (hitListHandle){
4881  //Find clusters associated with hits
4882  art::FindManyP<recob::Cluster> fmcl(hitListHandle,evt,fClusterModuleLabel);
4883  for (size_t i = 0; i < NHits && i < kMaxHits ; ++i){//loop over hits
4884  if (fmcl.isValid()){
4885  if (fmcl.at(i).size()!=0){
4886  fData->hit_clusterid[i] = fmcl.at(i)[0]->ID();
4887  // fData->hit_clusterKey[i] = fmcl.at(i)[0].key();
4888  }
4889  else
4890  fData->hit_clusterid[i] = -1;
4891  }
4892  }
4893  }
4894 }// end (fSaveHitInfo)
4895 
4897  lar_pandora::PFParticleVector particleVector;
4899  lar_pandora::VertexVector vertexVector;
4900  lar_pandora::PFParticlesToVertices particlesToVertices;
4901  lar_pandora::LArPandoraHelper::CollectVertices(evt, fPandoraNuVertexModuleLabel, vertexVector, particlesToVertices);
4902 
4903  short nprim = 0;
4904  for (unsigned int n = 0; n < particleVector.size(); ++n) {
4905  const art::Ptr<recob::PFParticle> particle = particleVector.at(n);
4906  if(particle->IsPrimary()) nprim++;
4907  }
4908 
4909  if (nprim > kMaxVertices){
4910  // got this error? consider increasing kMaxClusters
4911  // (or ask for a redesign using vectors)
4912  mf::LogError("AnaRootParser:limits") << "event has " << nprim
4913  << " nu neutrino vertices, only kMaxVertices=" << kMaxVertices << " stored in tree";
4914  }
4915 
4916  fData->nnuvtx = nprim;
4917 
4918  short iv = 0;
4919  for (unsigned int n = 0; n < particleVector.size(); ++n) {
4920  const art::Ptr<recob::PFParticle> particle = particleVector.at(n);
4921  if(particle->IsPrimary()) {
4922  lar_pandora::PFParticlesToVertices::const_iterator vIter = particlesToVertices.find(particle);
4923  if (particlesToVertices.end() != vIter) {
4924  const lar_pandora::VertexVector &vertexVector = vIter->second;
4925  if (!vertexVector.empty()) {
4926  if (vertexVector.size() == 1) {
4927  const art::Ptr<recob::Vertex> vertex = *(vertexVector.begin());
4928  double xyz[3] = {0.0, 0.0, 0.0} ;
4929  vertex->XYZ(xyz);
4930  fData->nuvtxx[iv] = xyz[0];
4931  fData->nuvtxy[iv] = xyz[1];
4932  fData->nuvtxz[iv] = xyz[2];
4933  fData->nuvtxpdg[iv] = particle->PdgCode();
4934  iv++;
4935  }
4936  }
4937  }
4938  }
4939  }
4940 } // save PandoraNuVertexInfo
4941 
4942 if (fSaveClusterInfo){
4943  fData->nclusters = (int) NClusters;
4944  if (NClusters > kMaxClusters){
4945  // got this error? consider increasing kMaxClusters
4946  // (or ask for a redesign using vectors)
4947  mf::LogError("AnaRootParser:limits") << "event has " << NClusters
4948  << " clusters, only kMaxClusters=" << kMaxClusters << " stored in tree";
4949  }
4950  for(unsigned int ic=0; ic<NClusters;++ic){//loop over clusters
4951  art::Ptr<recob::Cluster> clusterholder(clusterListHandle, ic);
4952  const recob::Cluster& cluster = *clusterholder;
4953  fData->clusterId[ic] = cluster.ID();
4954  fData->clusterView[ic] = cluster.View();
4955  // View 3 in LArSoft corresponds to View 0 in real life (3m long channels). View 2 in LArSoft corresponds to View 1 in real life (1m long channels).
4956  if(fData->clusterView[ic] == 3) {fData->clusterView[ic] = 0;}
4957  if(fData->clusterView[ic] == 2) {fData->clusterView[ic] = 1;}
4958  fData->cluster_isValid[ic] = cluster.isValid();
4959  fData->cluster_StartCharge[ic] = cluster.StartCharge();
4960  fData->cluster_StartAngle[ic] = cluster.StartAngle();
4961  fData->cluster_EndCharge[ic] = cluster.EndCharge();
4962  fData->cluster_EndAngle[ic] = cluster.EndAngle();
4963  fData->cluster_Integral[ic] = cluster.Integral();
4964  fData->cluster_IntegralAverage[ic] = cluster.IntegralAverage();
4965  fData->cluster_SummedADC[ic] = cluster.SummedADC();
4966  fData->cluster_SummedADCaverage[ic] = cluster.SummedADCaverage();
4967  fData->cluster_MultipleHitDensity[ic] = cluster.MultipleHitDensity();
4968  fData->cluster_Width[ic] = cluster.Width();
4969  fData->cluster_NHits[ic] = cluster.NHits();
4970  fData->cluster_StartWire[ic] = cluster.StartWire();
4971  fData->cluster_StartTick[ic] = cluster.StartTick();
4972  fData->cluster_EndWire[ic] = cluster.EndWire();
4973  fData->cluster_EndTick[ic] = cluster.EndTick();
4974 
4975  // Transform StartWire and EndWire to channels
4976  if(fData->clusterView[ic] == 1){fData->cluster_StartWire[ic]+=320; fData->cluster_EndWire[ic] += 320;}
4977 
4978  //Cosmic Tagger information for cluster
4979  /* art::FindManyP<anab::CosmicTag> fmcct(clusterListHandle,evt,fCosmicClusterTaggerAssocLabel);
4980  if (fmcct.isValid()){
4981  fData->cluncosmictags_tagger[ic] = fmcct.at(ic).size();
4982  if (fmcct.at(ic).size()>0){
4983  if(fmcct.at(ic).size()>1)
4984  std::cerr << "\n Warning : more than one cosmic tag per cluster in module! assigning the first tag to the cluster" << fCosmicClusterTaggerAssocLabel;
4985  fData->clucosmicscore_tagger[ic] = fmcct.at(ic).at(0)->CosmicScore();
4986  fData->clucosmictype_tagger[ic] = fmcct.at(ic).at(0)->CosmicType();
4987  }
4988  } */
4989  }//end loop over clusters
4990 }//end fSaveClusterInfo
4991 
4992 if (fSaveFlashInfo){
4993  fData->no_flashes = (int) NFlashes;
4994  if (NFlashes > kMaxFlashes) {
4995  // got this error? consider increasing kMaxHits
4996  // (or ask for a redesign using vectors)
4997  mf::LogError("AnaRootParser:limits") << "event has " << NFlashes
4998  << " flashes, only kMaxFlashes=" << kMaxFlashes << " stored in tree";
4999  }
5000  for (size_t i = 0; i < NFlashes && i < kMaxFlashes ; ++i){//loop over hits
5001  fData->flash_time[i] = flashlist[i]->Time();
5002  fData->flash_pe[i] = flashlist[i]->TotalPE();
5003  fData->flash_ycenter[i] = flashlist[i]->YCenter();
5004  fData->flash_zcenter[i] = flashlist[i]->ZCenter();
5005  fData->flash_ywidth[i] = flashlist[i]->YWidth();
5006  fData->flash_zwidth[i] = flashlist[i]->ZWidth();
5007  fData->flash_timewidth[i] = flashlist[i]->TimeWidth();
5008  }
5009 }
5010 
5012  fData->no_ExternCounts = (int) NExternCounts;
5013  if (NExternCounts > kMaxExternCounts) {
5014  // got this error? consider increasing kMaxHits
5015  // (or ask for a redesign using vectors)
5016  mf::LogError("AnaRootParser:limits") << "event has " << NExternCounts
5017  << " External Counters, only kMaxExternCounts=" << kMaxExternCounts << " stored in tree";
5018  }
5019  for (size_t i = 0; i < NExternCounts && i < kMaxExternCounts ; ++i){//loop over hits
5020  fData->externcounts_time[i] = countlist[i]->GetTrigTime();
5021  fData->externcounts_id[i] = countlist[i]->GetTrigID();
5022  }
5023 }
5024 
5025 
5026 // Declare object-ID-to-PFParticleID maps so we can assign hasPFParticle and PFParticleID to the tracks, showers, vertices.
5027 std::map<Short_t, Short_t> trackIDtoPFParticleIDMap, vertexIDtoPFParticleIDMap, showerIDtoPFParticleIDMap;
5028 
5029 //Save PFParticle information
5030 if (fSavePFParticleInfo){
5031  AnaRootParserDataStruct::PFParticleDataStruct& PFParticleData = fData->GetPFParticleData();
5032  size_t NPFParticles = pfparticlelist.size();
5033 
5034  PFParticleData.SetMaxPFParticles(std::max(NPFParticles, (size_t) 1));
5035  PFParticleData.Clear(); // clear all the data
5036 
5037  PFParticleData.nPFParticles = (short) NPFParticles;
5038 
5039  // now set the tree addresses to the newly allocated memory;
5040  // this creates the tree branches in case they are not there yet
5042 
5043  if (NPFParticles > PFParticleData.GetMaxPFParticles()) {
5044  mf::LogError("AnaRootParser:limits") << "event has " << NPFParticles
5045  << " PFParticles, only "
5046  << PFParticleData.GetMaxPFParticles() << " stored in tree";
5047  }
5048 
5049  lar_pandora::PFParticleVector neutrinoPFParticles;
5050  lar_pandora::LArPandoraHelper::SelectNeutrinoPFParticles(pfparticlelist, neutrinoPFParticles);
5051  PFParticleData.pfp_numNeutrinos = neutrinoPFParticles.size();
5052 
5053  for (size_t i = 0; i < std::min(neutrinoPFParticles.size(), (size_t)kMaxNPFPNeutrinos); ++i) {
5054  PFParticleData.pfp_neutrinoIDs[i] = neutrinoPFParticles[i]->Self();
5055  }
5056 
5057  if (neutrinoPFParticles.size() > kMaxNPFPNeutrinos)
5058  std::cerr << "Warning: there were " << neutrinoPFParticles.size() << " reconstructed PFParticle neutrinos; only the first " << kMaxNPFPNeutrinos << " being stored in tree" << std::endl;
5059 
5060  // Get a PFParticle-to-vertex map.
5061  lar_pandora::VertexVector allPfParticleVertices;
5062  lar_pandora::PFParticlesToVertices pfParticleToVertexMap;
5063  lar_pandora::LArPandoraHelper::CollectVertices(evt, fPFParticleModuleLabel, allPfParticleVertices, pfParticleToVertexMap);
5064 
5065  // Get a PFParticle-to-track map.
5066  lar_pandora::TrackVector allPfParticleTracks;
5067  lar_pandora::PFParticlesToTracks pfParticleToTrackMap;
5068  lar_pandora::LArPandoraHelper::CollectTracks(evt, fPFParticleModuleLabel, allPfParticleTracks, pfParticleToTrackMap);
5069 
5070  // Get a PFParticle-to-shower map.
5071  lar_pandora::ShowerVector allPfParticleShowers;
5072  lar_pandora::PFParticlesToShowers pfParticleToShowerMap;
5073  lar_pandora::LArPandoraHelper::CollectShowers(evt, fPFParticleModuleLabel, allPfParticleShowers, pfParticleToShowerMap);
5074 
5075  for (size_t i = 0; i < NPFParticles && i < PFParticleData.GetMaxPFParticles() ; ++i){
5076  PFParticleData.pfp_selfID[i] = pfparticlelist[i]->Self();
5077  PFParticleData.pfp_isPrimary[i] = (Short_t)pfparticlelist[i]->IsPrimary();
5078  PFParticleData.pfp_numDaughters[i] = pfparticlelist[i]->NumDaughters();
5079  PFParticleData.pfp_parentID[i] = pfparticlelist[i]->Parent();
5080  PFParticleData.pfp_pdgCode[i] = pfparticlelist[i]->PdgCode();
5081  PFParticleData.pfp_isNeutrino[i] = lar_pandora::LArPandoraHelper::IsNeutrino(pfparticlelist[i]);
5082 
5083  // Set the daughter IDs.
5084  std::vector<size_t> daughterIDs = pfparticlelist[i]->Daughters();
5085 
5086  for (size_t j = 0; j < daughterIDs.size(); ++j)
5087  PFParticleData.pfp_daughterIDs[i][j] = daughterIDs[j];
5088 
5089  // Set the vertex ID.
5090  auto vertexMapIter = pfParticleToVertexMap.find(pfparticlelist[i]);
5091  if (vertexMapIter != pfParticleToVertexMap.end()) {
5092  lar_pandora::VertexVector pfParticleVertices = vertexMapIter->second;
5093 
5094  if (pfParticleVertices.size() > 1)
5095  std::cerr << "Warning: there was more than one vertex found for PFParticle with ID " << pfparticlelist[i]->Self() << ", storing only one" << std::endl;
5096 
5097  if (pfParticleVertices.size() > 0) {
5098  PFParticleData.pfp_vertexID[i] = pfParticleVertices.at(0)->ID();
5099  vertexIDtoPFParticleIDMap.insert(std::make_pair(pfParticleVertices.at(0)->ID(), pfparticlelist[i]->Self()));
5100  }
5101  }
5102  else
5103  std::cerr << "Warning: there was no vertex found for PFParticle with ID " << pfparticlelist[i]->Self() << std::endl;
5104 
5105  if (lar_pandora::LArPandoraHelper::IsTrack(pfparticlelist[i])){
5106  PFParticleData.pfp_isTrack[i] = 1;
5107 
5108  // Set the track ID.
5109  auto trackMapIter = pfParticleToTrackMap.find(pfparticlelist[i]);
5110  if (trackMapIter != pfParticleToTrackMap.end()) {
5111  lar_pandora::TrackVector pfParticleTracks = trackMapIter->second;
5112 
5113  if (pfParticleTracks.size() > 1)
5114  std::cerr << "Warning: there was more than one track found for PFParticle with ID " << pfparticlelist[i]->Self() << std::endl;
5115 
5116  if (pfParticleTracks.size() > 0) {
5117  PFParticleData.pfp_trackID[i] = pfParticleTracks.at(0)->ID();
5118  trackIDtoPFParticleIDMap.insert(std::make_pair(pfParticleTracks.at(0)->ID(), pfparticlelist[i]->Self()));
5119  }
5120  }
5121  else
5122  std::cerr << "Warning: there was no track found for track-like PFParticle with ID " << pfparticlelist[i]->Self() << std::endl;
5123  }
5124  else
5125  PFParticleData.pfp_isTrack[i] = 0;
5126 
5127  if (lar_pandora::LArPandoraHelper::IsShower(pfparticlelist[i])) {
5128  PFParticleData.pfp_isShower[i] = 1;
5129  // Set the shower ID.
5130  auto showerMapIter = pfParticleToShowerMap.find(pfparticlelist[i]);
5131  if (showerMapIter != pfParticleToShowerMap.end()) {
5132  lar_pandora::ShowerVector pfParticleShowers = showerMapIter->second;
5133 
5134  if (pfParticleShowers.size() > 1)
5135  std::cerr << "Warning: there was more than one shower found for PFParticle with ID " << pfparticlelist[i]->Self() << std::endl;
5136 
5137  if (pfParticleShowers.size() > 0) {
5138  PFParticleData.pfp_showerID[i] = pfParticleShowers.at(0)->ID();
5139  showerIDtoPFParticleIDMap.insert(std::make_pair(pfParticleShowers.at(0)->ID(), pfparticlelist[i]->Self()));
5140  }
5141  }
5142  else
5143  std::cerr << "Warning: there was no shower found for shower-like PFParticle with ID " << pfparticlelist[i]->Self() << std::endl;
5144  }
5145  else
5146  PFParticleData.pfp_isShower[i] = 0;
5147 
5148  // Set the cluster IDs.
5149  auto clusterMapIter = pfParticleToClusterMap.find(pfparticlelist[i]);
5150  if (clusterMapIter != pfParticleToClusterMap.end()) {
5151  lar_pandora::ClusterVector pfParticleClusters = clusterMapIter->second;
5152  PFParticleData.pfp_numClusters[i] = pfParticleClusters.size();
5153 
5154  for (size_t j = 0; j < pfParticleClusters.size(); ++j)
5155  PFParticleData.pfp_clusterIDs[i][j] = pfParticleClusters[j]->ID();
5156  }
5157  //else
5158  // std::cerr << "Warning: there were no clusters found for PFParticle with ID " << pfparticlelist[i]->Self() << std::endl;
5159  }
5160 } // if fSavePFParticleInfo
5161 
5162 if (fSaveShowerInfo){
5163 
5164  // fill data from all the shower algorithms
5165  for (size_t iShowerAlgo = 0; iShowerAlgo < NShowerAlgos; ++iShowerAlgo) {
5167  = fData->GetShowerData(iShowerAlgo);
5168  std::vector<recob::Shower> const* pShowers = showerList[iShowerAlgo];
5169  art::Handle< std::vector<recob::Shower> > showerHandle = showerListHandle[iShowerAlgo];
5170 
5171  if (pShowers){
5172  FillShowers(ShowerData, *pShowers, fSavePFParticleInfo, showerIDtoPFParticleIDMap);
5173 
5174  if(fMVAPIDShowerModuleLabel[iShowerAlgo].size()){
5175  art::FindOneP<anab::MVAPIDResult> fmvapid(showerHandle, evt, fMVAPIDShowerModuleLabel[iShowerAlgo]);
5176  if(fmvapid.isValid()){
5177  for(unsigned int iShower=0;iShower<showerHandle->size();++iShower){
5178  const art::Ptr<anab::MVAPIDResult> pid = fmvapid.at(iShower);
5179  ShowerData.shwr_pidmvamu[iShower] = pid->mvaOutput.at("muon");
5180  ShowerData.shwr_pidmvae[iShower] = pid->mvaOutput.at("electron");
5181  ShowerData.shwr_pidmvapich[iShower] = pid->mvaOutput.at("pich");
5182  ShowerData.shwr_pidmvaphoton[iShower] = pid->mvaOutput.at("photon");
5183  ShowerData.shwr_pidmvapr[iShower] = pid->mvaOutput.at("proton");
5184  }
5185  } // fmvapid.isValid()
5186  }
5187  }
5188  else ShowerData.MarkMissing(fTree); // tree should reflect lack of data
5189  } // for iShowerAlgo
5190 
5191 } // if fSaveShowerInfo
5192 
5193 //track information for multiple trackers
5194 if (fSaveTrackInfo) {
5195 
5196  // Get Geometry
5198 
5199  for (unsigned int iTracker=0; iTracker < NTrackers; ++iTracker){
5200  AnaRootParserDataStruct::TrackDataStruct& TrackerData = fData->GetTrackerData(iTracker);
5201 
5202  size_t NTracks = tracklist[iTracker].size();
5203 
5204  // allocate enough space for this number of tracks (but at least for one of them!)
5205  TrackerData.SetMaxTracks(std::max(NTracks, (size_t) 1));
5206  TrackerData.Clear(); // clear all the data
5207 
5208  TrackerData.ntracks = (int) NTracks;
5209  /*
5210  //First loop over tracks to get array sizes (number of hits in each track)
5211  for(size_t iTrk=0; iTrk < NTracks; ++iTrk){//loop over tracks
5212  art::FindMany<anab::Calorimetry> fmcaltemp(trackListHandle[iTracker], evt, fCalorimetryModuleLabel[iTracker]);
5213  if (fmcaltemp.isValid()){
5214  std::vector<const anab::Calorimetry*> calostemp = fmcaltemp.at(iTrk);
5215  for (size_t ical = 0; ical<calostemp.size(); ++ical){
5216  if (!calostemp[ical]) continue;
5217  if (!calostemp[ical]->PlaneID().isValid) continue;
5218  int planenumtemp = calostemp[ical]->PlaneID().Plane;
5219  if (planenumtemp<0||planenumtemp>2) continue;
5220  //For now make the second argument as 13 for muons.
5221  // const size_t NHitsTemp = calostemp[ical] -> dEdx().size();
5222  // TrackerData.NHitsInAllTracks+=(int) NHitsTemp;
5223  // fData->NHitsInAllTracks+=(int) NHitsTemp;
5224  } // for calorimetry info
5225  } // if has calorimetry info
5226  }//loop over tracks
5227  */
5228 
5229  // now set the tree addresses to the newly allocated memory;
5230  // this creates the tree branches in case they are not there yet
5231  SetTrackerAddresses(iTracker);
5232  if (NTracks > TrackerData.GetMaxTracks()) {
5233  // got this error? it might be a bug,
5234  // since we are supposed to have allocated enough space to fit all tracks
5235  mf::LogError("AnaRootParser:limits") << "event has " << NTracks
5236  << " " << fTrackModuleLabel[iTracker] << " tracks, only "
5237  << TrackerData.GetMaxTracks() << " stored in tree";
5238  }
5239 
5240  //call the track momentum algorithm that gives you momentum based on track range
5241  // - change the minimal track length requirement to 50 cm
5243 
5244  recob::MCSFitResult res;
5245 
5246  int HitIterator=0;
5247  int HitIterator2=0;
5248 
5249  int trueID = -9999;
5250  float maxe = -9999.;
5251  float purity = -9999.;
5252 
5253  for(size_t iTrk=0; iTrk < NTracks; ++iTrk){//loop over tracks
5254 
5255  //save t0 from reconstructed flash track matching for every track
5256  art::FindManyP<anab::T0> fmt0(trackListHandle[iTracker],evt,fFlashT0FinderLabel[iTracker]);
5257  if (fmt0.isValid()){
5258  if(fmt0.at(iTrk).size()>0){
5259  if(fmt0.at(iTrk).size()>1)
5260  std::cerr << "\n Warning : more than one cosmic tag per track in module! assigning the first tag to the track" << fFlashT0FinderLabel[iTracker];
5261  TrackerData.trkflashT0[iTrk] = fmt0.at(iTrk).at(0)->Time();
5262  }
5263  }
5264 
5265  //save t0 from reconstructed flash track matching for every track
5266  art::FindManyP<anab::T0> fmmct0(trackListHandle[iTracker],evt,fMCT0FinderLabel[iTracker]);
5267  if (fmmct0.isValid()){
5268  if(fmmct0.at(iTrk).size()>0){
5269  if(fmmct0.at(iTrk).size()>1)
5270  std::cerr << "\n Warning : more than one cosmic tag per track in module! assigning the first tag to the cluster" << fMCT0FinderLabel[iTracker];
5271  TrackerData.trktrueT0[iTrk] = fmmct0.at(iTrk).at(0)->Time();
5272  }
5273  }
5274 
5275  //Cosmic Tagger information
5276  art::FindManyP<anab::CosmicTag> fmct(trackListHandle[iTracker],evt,fCosmicTaggerAssocLabel[iTracker]);
5277  if (fmct.isValid()){
5278  TrackerData.trkncosmictags_tagger[iTrk] = fmct.at(iTrk).size();
5279  if (fmct.at(iTrk).size()>0){
5280  if(fmct.at(iTrk).size()>1)
5281  std::cerr << "\n Warning : more than one cosmic tag per track in module! assigning the first tag to the track" << fCosmicTaggerAssocLabel[iTracker];
5282  TrackerData.trkcosmicscore_tagger[iTrk] = fmct.at(iTrk).at(0)->CosmicScore();
5283  TrackerData.trkcosmictype_tagger[iTrk] = fmct.at(iTrk).at(0)->CosmicType();
5284  }
5285  }
5286 
5287  //Containment Tagger information
5288  art::FindManyP<anab::CosmicTag> fmcnt(trackListHandle[iTracker],evt,fContainmentTaggerAssocLabel[iTracker]);
5289  if (fmcnt.isValid()){
5290  TrackerData.trkncosmictags_containmenttagger[iTrk] = fmcnt.at(iTrk).size();
5291  if (fmcnt.at(iTrk).size()>0){
5292  if(fmcnt.at(iTrk).size()>1)
5293  std::cerr << "\n Warning : more than one containment tag per track in module! assigning the first tag to the track" << fContainmentTaggerAssocLabel[iTracker];
5294  TrackerData.trkcosmicscore_containmenttagger[iTrk] = fmcnt.at(iTrk).at(0)->CosmicScore();
5295  TrackerData.trkcosmictype_containmenttagger[iTrk] = fmcnt.at(iTrk).at(0)->CosmicType();
5296  }
5297  }
5298 
5299  //Flash match compatibility information
5300  //Unlike CosmicTagger, Flash match doesn't assign a cosmic tag for every track. For those tracks, AnaRootParser initializes them with -999 or -9999
5301  art::FindManyP<anab::CosmicTag> fmbfm(trackListHandle[iTracker],evt,fFlashMatchAssocLabel[iTracker]);
5302  if (fmbfm.isValid()){
5303  TrackerData.trkncosmictags_flashmatch[iTrk] = fmbfm.at(iTrk).size();
5304  if (fmbfm.at(iTrk).size()>0){
5305  if(fmbfm.at(iTrk).size()>1)
5306  std::cerr << "\n Warning : more than one cosmic tag per track in module! assigning the first tag to the track" << fFlashMatchAssocLabel[iTracker];
5307  TrackerData.trkcosmicscore_flashmatch[iTrk] = fmbfm.at(iTrk).at(0)->CosmicScore();
5308  TrackerData.trkcosmictype_flashmatch[iTrk] = fmbfm.at(iTrk).at(0)->CosmicType();
5309  //std::cout<<"\n"<<evt.event()<<"\t"<<iTrk<<"\t"<<fmbfm.at(iTrk).at(0)->CosmicScore()<<"\t"<<fmbfm.at(iTrk).at(0)->CosmicType();
5310  }
5311  }
5312 
5313  art::Ptr<recob::Track> ptrack(trackListHandle[iTracker], iTrk);
5314  const recob::Track& track = *ptrack;
5315 
5316  TVector3 pos, dir_start, dir_end, end;
5317  TVector3 dir_start_flipped, dir_end_flipped;
5318  double tlen = 0., mom = 0.;
5319  int TrackID = -1;
5320 
5321  int ntraj = track.NumberTrajectoryPoints();
5322  if (ntraj > 0) {
5323  pos = track.Vertex<TVector3>();
5324  dir_start = track.VertexDirection<TVector3>();
5325  dir_end = track.EndDirection<TVector3>();
5326  end = track.End<TVector3>();
5327 
5328  dir_start_flipped.SetXYZ(dir_start.Z(), dir_start.Y(), dir_start.X());
5329  dir_end_flipped.SetXYZ(dir_end.Z(), dir_end.Y(), dir_end.X());
5330 
5331  tlen = length(track);
5332  if(track.NumberTrajectoryPoints() > 0)
5333  mom = track.VertexMomentum();
5334  // fill non-bezier-track reco branches
5335  TrackID = track.ID();
5336 
5337  double theta_xz = std::atan2(dir_start.X(), dir_start.Z());
5338  double theta_yz = std::atan2(dir_start.Y(), dir_start.Z());
5339  double dpos = bdist(pos); // FIXME - Passing an uncorrected position....
5340  double dend = bdist(end); // FIXME - Passing an uncorrected position....
5341 
5342  TrackerData.trkId[iTrk] = TrackID;
5343  TrackerData.trkstartx[iTrk] = pos.X();
5344  TrackerData.trkstarty[iTrk] = pos.Y();
5345  TrackerData.trkstartz[iTrk] = pos.Z();
5346  TrackerData.trkstartd[iTrk] = dpos;
5347  TrackerData.trkendx[iTrk] = end.X();
5348  TrackerData.trkendy[iTrk] = end.Y();
5349  TrackerData.trkendz[iTrk] = end.Z();
5350  TrackerData.trkendd[iTrk] = dend;
5351  TrackerData.trkstarttheta[iTrk] = (180.0/3.14159)*dir_start_flipped.Theta();
5352  TrackerData.trkstartphi[iTrk] = (180.0/3.14159)*dir_start_flipped.Phi();
5353  TrackerData.trkstartdirectionx[iTrk] = dir_start.X();
5354  TrackerData.trkstartdirectiony[iTrk] = dir_start.Y();
5355  TrackerData.trkstartdirectionz[iTrk] = dir_start.Z();
5356 
5357  if(fLogLevel >= 2)
5358  {
5359  std::cout << std::endl;
5360  std::cout << "start.X(): " << pos.X() << "\t" << "start.Y(): " << pos.Y() << "\t" << "start.Z(): " << pos.Z() << std::endl;
5361  std::cout << "end.X(): " << end.X() << "\t" << "end.Y(): " << end.Y() << "\t" << "end.Z(): " << end.Z() << std::endl;
5362  std::cout << "dir_start.X(): " << dir_start.X() << "\t" << "dir_start.Y(): " << dir_start.Y() << "\t" << "dir_start.Z(): " << dir_start.Z() << std::endl;
5363  std::cout << "dir_end.X(): " << dir_end.X() << "\t" << "dir_end.Y(): " << dir_end.Y() << "\t" << "dir_end.Z(): " << dir_end.Z() << std::endl;
5364  std::cout << "dir_start_flipped.Theta(): " << (180.0/3.14159)*dir_start_flipped.Theta() << "\t" << "dir_start_flipped.Phi(): " << (180.0/3.14159)*dir_start_flipped.Phi() << std::endl;
5365  std::cout << "dir_end_flipped.Theta(): " << (180.0/3.14159)*dir_end_flipped.Theta() << "\t" << "dir_end_flipped.Phi(): " << (180.0/3.14159)*dir_end_flipped.Phi() << std::endl;
5366  std::cout << std::endl;
5367  }
5368 
5369  TrackerData.trkendtheta[iTrk] = (180.0/3.14159)*dir_end_flipped.Theta();
5370  TrackerData.trkendphi[iTrk] = (180.0/3.14159)*dir_end_flipped.Phi();
5371  TrackerData.trkenddirectionx[iTrk] = dir_end.X();
5372  TrackerData.trkenddirectiony[iTrk] = dir_end.Y();
5373  TrackerData.trkenddirectionz[iTrk] = dir_end.Z();
5374 
5375  TrackerData.trkthetaxz[iTrk] = theta_xz;
5376  TrackerData.trkthetayz[iTrk] = theta_yz;
5377  TrackerData.trkmom[iTrk] = mom;
5378  TrackerData.trkchi2PerNDF[iTrk] = track.Chi2PerNdof();
5379  TrackerData.trkNDF[iTrk] = track.Ndof();
5380  TrackerData.trklen[iTrk] = tlen;
5381  TrackerData.trklenstraightline[iTrk] = sqrt(pow(pos.X()-end.X(),2) + pow(pos.Y()-end.Y(),2) + pow(pos.Z()-end.Z(),2));
5382  TrackerData.trkmomrange[iTrk] = trkm.GetTrackMomentum(tlen,13);
5383  TrackerData.trkmommschi2[iTrk] = trkm.GetMomentumMultiScatterChi2(ptrack);
5384  TrackerData.trkmommsllhd[iTrk] = trkm.GetMomentumMultiScatterLLHD(ptrack);
5385 
5386  //uBoone MCS
5387  res = fMCSFitter.fitMcs(*ptrack);
5388  TrackerData.trkmommscmic[iTrk] = res.bestMomentum();
5389  TrackerData.trkmommscfwd[iTrk] = res.fwdMomentum();
5390  TrackerData.trkmommscbwd[iTrk] = res.bwdMomentum();
5391  TrackerData.trkmommscllfwd[iTrk] = res.fwdLogLikelihood();
5392  TrackerData.trkmommscllbwd[iTrk] = res.bwdLogLikelihood();
5393 
5394 
5395  if (fSavePFParticleInfo) {
5396  auto mapIter = trackIDtoPFParticleIDMap.find(TrackID);
5397  if (mapIter != trackIDtoPFParticleIDMap.end()) {
5398  // This track has a corresponding PFParticle.
5399  TrackerData.trkhasPFParticle[iTrk] = 1;
5400  TrackerData.trkPFParticleID[iTrk] = mapIter->second;
5401  }
5402  else
5403  TrackerData.trkhasPFParticle[iTrk] = 0;
5404  }
5405 
5406  } // if we have trajectory
5407 
5408  // find vertices associated with this track
5409  /*
5410  art::FindMany<recob::Vertex> fmvtx(trackListHandle[iTracker], evt, fVertexModuleLabel[iTracker]);
5411  if(fmvtx.isValid()) {
5412  std::vector<const recob::Vertex*> verts = fmvtx.at(iTrk);
5413  // should have two at most
5414  for(size_t ivx = 0; ivx < verts.size(); ++ivx) {
5415  verts[ivx]->XYZ(xyz);
5416  // find the vertex in TrackerData to get the index
5417  short theVtx = -1;
5418  for(short jvx = 0; jvx < TrackerData.nvtx; ++jvx) {
5419  if(TrackerData.vtx[jvx][2] == xyz[2]) {
5420  theVtx = jvx;
5421  break;
5422  }
5423  } // jvx
5424  // decide if it should be assigned to the track Start or End.
5425  // A simple dz test should suffice
5426  if(fabs(xyz[2] - TrackerData.trkstartz[iTrk]) <
5427  fabs(xyz[2] - TrackerData.trkendz[iTrk])) {
5428  TrackerData.trksvtxid[iTrk] = theVtx;
5429  } else {
5430  TrackerData.trkevtxid[iTrk] = theVtx;
5431  }
5432  } // vertices
5433  } // fmvtx.isValid()
5434  */
5435 
5436 
5437  /* //commented out because now have several Vertices
5438  Float_t minsdist = 10000;
5439  Float_t minedist = 10000;
5440  for (int ivx = 0; ivx < NVertices && ivx < kMaxVertices; ++ivx){
5441  Float_t sdist = sqrt(pow(TrackerData.trkstartx[iTrk]-VertexData.vtxx[ivx],2)+
5442  pow(TrackerData.trkstarty[iTrk]-VertexData.vtxy[ivx],2)+
5443  pow(TrackerData.trkstartz[iTrk]-VertexData.vtxz[ivx],2));
5444  Float_t edist = sqrt(pow(TrackerData.trkendx[iTrk]-VertexData.vtxx[ivx],2)+
5445  pow(TrackerData.trkendy[iTrk]-VertexData.vtxy[ivx],2)+
5446  pow(TrackerData.trkendz[iTrk]-VertexData.vtxz[ivx],2));
5447  if (sdist<minsdist){
5448  minsdist = sdist;
5449  if (minsdist<10) TrackerData.trksvtxid[iTrk] = ivx;
5450  }
5451  if (edist<minedist){
5452  minedist = edist;
5453  if (minedist<10) TrackerData.trkevtxid[iTrk] = ivx;
5454  }
5455  }*/
5456 
5457  // find particle ID info
5458  /*
5459  art::FindMany<anab::ParticleID> fmpid(trackListHandle[iTracker], evt, fParticleIDModuleLabel[iTracker]);
5460  if(fmpid.isValid()) {
5461  std::vector<const anab::ParticleID*> pids = fmpid.at(iTrk);
5462  //if(pids.size() > 1) {
5463  //mf::LogError("AnaRootParser:limits")
5464  //<< "the " << fTrackModuleLabel[iTracker] << " track #" << iTrk
5465  //<< " has " << pids.size()
5466  //<< " set of ParticleID variables. Only one stored in the tree";
5467  //}
5468  for (size_t ipid = 0; ipid < pids.size(); ++ipid){
5469  if (!pids[ipid]->PlaneID().isValid) continue;
5470  int planenum = pids[ipid]->PlaneID().Plane;
5471  if (planenum<0||planenum>2) continue;
5472  TrackerData.trkpidpdg[iTrk][planenum] = pids[ipid]->Pdg();
5473  TrackerData.trkpidchi[iTrk][planenum] = pids[ipid]->MinChi2();
5474  TrackerData.trkpidchipr[iTrk][planenum] = pids[ipid]->Chi2Proton();
5475  TrackerData.trkpidchika[iTrk][planenum] = pids[ipid]->Chi2Kaon();
5476  TrackerData.trkpidchipi[iTrk][planenum] = pids[ipid]->Chi2Pion();
5477  TrackerData.trkpidchimu[iTrk][planenum] = pids[ipid]->Chi2Muon();
5478  TrackerData.trkpidpida[iTrk][planenum] = pids[ipid]->PIDA();
5479  }
5480  } // fmpid.isValid()
5481  */
5482  if(fMVAPIDTrackModuleLabel[iTracker].size()){
5483  art::FindOneP<anab::MVAPIDResult> fmvapid(trackListHandle[iTracker], evt, fMVAPIDTrackModuleLabel[iTracker]);
5484  if(fmvapid.isValid()) {
5485  const art::Ptr<anab::MVAPIDResult> pid = fmvapid.at(iTrk);
5486  TrackerData.trkpidmvamu[iTrk] = pid->mvaOutput.at("muon");
5487  TrackerData.trkpidmvae[iTrk] = pid->mvaOutput.at("electron");
5488  TrackerData.trkpidmvapich[iTrk] = pid->mvaOutput.at("pich");
5489  TrackerData.trkpidmvaphoton[iTrk] = pid->mvaOutput.at("photon");
5490  TrackerData.trkpidmvapr[iTrk] = pid->mvaOutput.at("proton");
5491  } // fmvapid.isValid()
5492  }
5493 
5494 
5495  art::FindManyP<recob::Hit, recob::TrackHitMeta> fmthm(trackListHandle[iTracker], evt, "pmtrack");
5496 
5497 // if (fmthm.isValid()){
5498  auto vhit = fmthm.at(iTrk);
5499  auto vmeta = fmthm.data(iTrk);
5500 
5501  TrackerData.NHitsPerTrack[iTrk] = vhit.size();
5502  art::FindManyP<recob::SpacePoint> fmspts(vhit, evt, "pmtrack");
5503 
5504  int NHitsView0 = 0;
5505  int NHitsView1 = 0;
5506 
5507  if(fLogLevel >= 2)
5508  {
5509  std::cout << "track.NumberTrajectoryPoints(): " << track.NumberTrajectoryPoints() << std::endl;
5510  std::cout << "track.NPoints(): " << track.NPoints() << std::endl;
5511  std::cout << "vhit.size(): " << vhit.size() << std::endl;
5512  std::cout << "vmeta.size(): " << vmeta.size() << std::endl;
5513  std::cout << "fmspts.size(): " << fmspts.size() << std::endl;
5514  }
5515 
5516  for (unsigned int h = 0; h < vhit.size(); h++)
5517  {
5518  //corrected pitch
5519  double angleToVert = geomhandle->WireAngleToVertical(vhit[h]->View(), vhit[h]->WireID().TPC, vhit[h]->WireID().Cryostat) - 0.5*::util::pi<>();
5520  const TVector3& dir = tracklist[iTracker][iTrk]->DirectionAtPoint<TVector3>(h);
5521  const TVector3& loc = tracklist[iTracker][iTrk]->LocationAtPoint<TVector3>(h);
5522  double cosgamma = std::abs(std::sin(angleToVert)*dir.Y() + std::cos(angleToVert)*dir.Z());
5523 
5524 
5525  TrackerData.hittrklocaltrackdirectionx[HitIterator2] = dir.X();
5526  TrackerData.hittrklocaltrackdirectiony[HitIterator2] = dir.Y();
5527  TrackerData.hittrklocaltrackdirectionz[HitIterator2] = dir.Z();
5528 
5529 
5530  //XYZ
5531  std::vector< art::Ptr<recob::SpacePoint> > sptv = fmspts.at(h);
5532  TrackerData.hittrkx[HitIterator2] = sptv[0]->XYZ()[0];
5533  TrackerData.hittrky[HitIterator2] = sptv[0]->XYZ()[1];
5534  TrackerData.hittrkz[HitIterator2] = sptv[0]->XYZ()[2];
5535 
5536  TVector3 dir_hit_flipped;
5537  dir_hit_flipped.SetXYZ(dir.Z(), dir.Y(), dir.X());
5538 
5539  TrackerData.hittrklocaltrackdirectiontheta[HitIterator2] = (180.0/3.14159)*dir_hit_flipped.Theta();
5540  TrackerData.hittrklocaltrackdirectionphi[HitIterator2] = (180.0/3.14159)*dir_hit_flipped.Phi();
5541 
5542  //dx
5543  if(vhit[h]->WireID().Plane == 0) TrackerData.hittrkpitchC[HitIterator2] = std::abs(geomhandle->WirePitch()/( sin(dir_hit_flipped.Theta())*sin(dir_hit_flipped.Phi()) ));
5544  if(vhit[h]->WireID().Plane == 1) TrackerData.hittrkpitchC[HitIterator2] = std::abs(geomhandle->WirePitch()/( sin(dir_hit_flipped.Theta())*cos(dir_hit_flipped.Phi()) ));
5545 
5546  TrackerData.hittrkds[HitIterator2] = vmeta[h]->Dx();
5547 
5548  if(fLogLevel >= 2)
5549  {
5550  std::cout << "pos.X(): " << sptv[0]->XYZ()[0] << "\t" << "pos.Y(): " << sptv[0]->XYZ()[1] << "\t" << "pos.Z(): " << sptv[0]->XYZ()[2] << std::endl;
5551  std::cout << "pos2.X(): " << loc.X() << "\t" << "pos2.Y(): " << loc.Y() << "\t" << "pos2.Z(): " << loc.Z() << std::endl;
5552  std::cout << "dir.X(): " << dir.X() << "\t" << "dir.Y(): " << dir.Y() << "\t" << "dir.Z(): " << dir.Z() << std::endl;
5553  std::cout << "dir_hit_flipped.Theta(): " << (180.0/3.14159)*dir_hit_flipped.Theta() << "\t" << "dir_hit_flipped.Phi(): " << (180.0/3.14159)*dir_hit_flipped.Phi() << std::endl;
5554  std::cout << "vmeta[h]->Dx(): " << vmeta[h]->Dx() << std::endl;
5555  std::cout << "Dx corrected pitch old: " << geomhandle->WirePitch()/cosgamma << std::endl;
5556  std::cout << "Dx corrected pitch new: " << TrackerData.hittrkpitchC[HitIterator2] << std::endl;
5557  std::cout << "view: " << vhit[h]->WireID().Plane << std::endl;
5558  }
5559 
5560  //hit variables
5561  TrackerData.hittrkchannel[HitIterator2] = vhit[h]->Channel();
5562  TrackerData.hittrktpc[HitIterator2] = vhit[h]->WireID().TPC;
5563  TrackerData.hittrkview[HitIterator2] = vhit[h]->WireID().Plane;
5564  TrackerData.hittrkwire[HitIterator2] = vhit[h]->WireID().Wire;
5565  TrackerData.hittrkpeakT[HitIterator2] = vhit[h]->PeakTime();
5566  TrackerData.hittrkchargeintegral[HitIterator2] = vhit[h]->Integral();
5567  TrackerData.hittrkph[HitIterator2] = vhit[h]->PeakAmplitude();
5568  TrackerData.hittrkchargesum[HitIterator2] = vhit[h]->SummedADC();
5569  TrackerData.hittrkstarT[HitIterator2] = vhit[h]->StartTick();
5570  TrackerData.hittrkendT[HitIterator2] = vhit[h]->EndTick();
5571  TrackerData.hittrkrms[HitIterator2] = vhit[h]->RMS();
5572  TrackerData.hittrkgoddnessofFit[HitIterator2] = vhit[h]->GoodnessOfFit();
5573  TrackerData.hittrkmultiplicity[HitIterator2] = vhit[h]->Multiplicity();
5574 
5575  //quantities from backtracker are different from the real value in MC
5576  if( fIsMC )
5577  HitsBackTrack(clockData, vhit[h], trueID, maxe, purity );
5578 
5579  TrackerData.hittrktrueID[HitIterator2] = trueID;
5580  TrackerData.hittrktrueEnergyMax[HitIterator2] = maxe;
5581  TrackerData.hittrktrueEnergyFraction[HitIterator2] = purity;
5582 
5583  HitIterator2++;
5584 
5585  if(vhit[h]->WireID().Plane == 0) NHitsView0++;
5586  if(vhit[h]->WireID().Plane == 1) NHitsView1++;
5587  }
5588  TrackerData.ntrkhitsperview[iTrk][0] = NHitsView0;
5589  TrackerData.ntrkhitsperview[iTrk][1] = NHitsView1;
5590 
5591 // }
5592 
5593 /*
5594  std::cout << "tracklist[iTracker][iTrk]->NumberTrajectoryPoints(): " << tracklist[iTracker][iTrk]->NumberTrajectoryPoints() << std::endl;
5595  for(size_t itp = 0; itp < tracklist[iTracker][iTrk]->NumberTrajectoryPoints(); ++itp)
5596  {
5597  const TVector3& pos = tracklist[iTracker][iTrk]->LocationAtPoint(itp);
5598  }
5599 */
5600 //
5601 // art::FindManyP<recob::Hit> fmht(trackListHandle[iTracker], evt, fTrackModuleLabel);
5602 // std::vector< art::Ptr<recob::Hit> > allHits = fmht.at(trkIter);
5603 // art::FindManyP<recob::SpacePoint> fmspts(allHits, evt, fSpacePointModuleLabel);
5604 //
5605 /*
5606  art::FindManyP<recob::SpacePoint> fmspts(vhit, evt, "pmtrack");
5607  for (size_t h = 0; h < vhit.size(); ++h)
5608  {
5609  std::vector< art::Ptr<recob::SpacePoint> > sptv = fmspts.at(h);
5610 
5611  for (size_t j = 0; j < sptv.size(); ++j)
5612  {
5613  std::cout << "sptv[j]->XYZ()[0]: " << sptv[j]->XYZ()[0] << std::endl;
5614  std::cout << "sptv[j]->XYZ()[1]: " << sptv[j]->XYZ()[1] << std::endl;
5615  std::cout << "sptv[j]->XYZ()[2]: " << sptv[j]->XYZ()[2] << std::endl;
5616  std::cout << "sptv[j]->ErrXYZ()[0]: " << sptv[j]->ErrXYZ()[0] << std::endl;
5617  std::cout << "sptv[j]->ErrXYZ()[1]: " << sptv[j]->ErrXYZ()[1] << std::endl;
5618  std::cout << "sptv[j]->ErrXYZ()[2]: " << sptv[j]->ErrXYZ()[2] << std::endl;
5619  }
5620  }
5621 */
5622 //
5623 
5624 
5625 /////////////////////
5626  art::FindMany<anab::Calorimetry> fmcal(trackListHandle[iTracker], evt, fCalorimetryModuleLabel[iTracker]);
5627  if (fmcal.isValid()){
5628  std::vector<const anab::Calorimetry*> calos = fmcal.at(iTrk);
5629  if (calos.size() > TrackerData.GetMaxPlanesPerTrack(iTrk)) {
5630  // if you get this message, there is probably a bug somewhere since
5631  // the calorimetry planes should be 3.
5632  mf::LogError("AnaRootParser:limits")
5633  << "the " << fTrackModuleLabel[iTracker] << " track #" << iTrk
5634  << " has " << calos.size() << " planes for calorimetry , only "
5635  << TrackerData.GetMaxPlanesPerTrack(iTrk) << " stored in tree";
5636  }
5637 
5638  // for (size_t ical = 0; ical<calos.size(); ++ical){
5639  for (size_t ical = calos.size() - 1; ical <= 1 ; --ical){ //reverse order so that we access info on plane 0 (which is view 0 in real life) first
5640  if (!calos[ical]) continue;
5641  if (!calos[ical]->PlaneID().isValid) continue;
5642  int planenum = calos[ical]->PlaneID().Plane;
5643  if (planenum<0||planenum>1) continue; //only two planes (0 and 1) in dual phase
5644  TrackerData.trkke[iTrk][planenum] = calos[ical]->KineticEnergy();
5645  TrackerData.trkrange[iTrk][planenum] = calos[ical]->Range();
5646  //For now make the second argument as 13 for muons.
5647  TrackerData.trkpitchc[iTrk][planenum]= calos[ical] -> TrkPitchC();
5648  const size_t NHits = calos[ical] -> dEdx().size();
5649 // TrackerData.ntrkhitsperview[iTrk][planenum] = (int) NHits;
5650  if (NHits > TrackerData.GetMaxHitsPerTrack(iTrk, planenum)) {
5651  // if you get this error, you'll have to increase kMaxTrackHits
5652  mf::LogError("AnaRootParser:limits")
5653  << "the " << fTrackModuleLabel[iTracker] << " track #" << iTrk
5654  << " has " << NHits << " hits on calorimetry plane #" << planenum
5655  <<", only "
5656  << TrackerData.GetMaxHitsPerTrack(iTrk, planenum) << " stored in tree";
5657  }
5658  if (!isCosmics){
5659  for(size_t iTrkHit = 0; iTrkHit < NHits && iTrkHit < TrackerData.GetMaxHitsPerTrack(iTrk, planenum); ++iTrkHit) {
5660  TrackerData.trkdedx[iTrk][planenum][iTrkHit] = (calos[ical] -> dEdx())[iTrkHit];
5661  TrackerData.trkdqdx[iTrk][planenum][iTrkHit] = (calos[ical] -> dQdx())[iTrkHit];
5662  TrackerData.trkresrg[iTrk][planenum][iTrkHit] = (calos[ical] -> ResidualRange())[iTrkHit];
5663  TrackerData.trktpc[iTrk][planenum][iTrkHit] = (calos[ical] -> PlaneID()).TPC;
5664  const auto& TrkPos = (calos[ical] -> XYZ())[iTrkHit];
5665  auto& TrkXYZ = TrackerData.trkxyz[iTrk][planenum][iTrkHit];
5666  TrkXYZ[0] = TrkPos.X();
5667  TrkXYZ[1] = TrkPos.Y();
5668  TrkXYZ[2] = TrkPos.Z();
5669  //TrackerData.trkdedx2.push_back((calos[ical] -> dEdx())[iTrkHit]);
5670  TrackerData.trkdedx2[HitIterator] = (calos[ical] -> dEdx())[iTrkHit];
5671  TrackerData.trkdqdx2[HitIterator] = (calos[ical] -> dQdx())[iTrkHit];
5672  TrackerData.trktpc2[HitIterator] = (calos[ical] -> PlaneID()).TPC;
5673  TrackerData.trkx2[HitIterator] = TrkPos.X();
5674  TrackerData.trky2[HitIterator] = TrkPos.Y();
5675  TrackerData.trkz2[HitIterator] = TrkPos.Z();
5676  HitIterator++;
5677  } // for track hits
5678  }
5679  } // for calorimetry info
5680 
5681 
5682  //best plane
5683  if(TrackerData.ntrkhitsperview[iTrk][0] > TrackerData.ntrkhitsperview[iTrk][1] && TrackerData.ntrkhitsperview[iTrk][0] > TrackerData.ntrkhitsperview[iTrk][2]) TrackerData.trkpidbestplane[iTrk] = 0;
5684  else if(TrackerData.ntrkhitsperview[iTrk][1] > TrackerData.ntrkhitsperview[iTrk][0] && TrackerData.ntrkhitsperview[iTrk][1] > TrackerData.ntrkhitsperview[iTrk][2]) TrackerData.trkpidbestplane[iTrk] = 1;
5685  else if(TrackerData.ntrkhitsperview[iTrk][2] > TrackerData.ntrkhitsperview[iTrk][0] && TrackerData.ntrkhitsperview[iTrk][2] > TrackerData.ntrkhitsperview[iTrk][1]) TrackerData.trkpidbestplane[iTrk] = 2;
5686  else if(TrackerData.ntrkhitsperview[iTrk][2] == TrackerData.ntrkhitsperview[iTrk][0] && TrackerData.ntrkhitsperview[iTrk][2] > TrackerData.ntrkhitsperview[iTrk][1]) TrackerData.trkpidbestplane[iTrk] = 2;
5687  else if(TrackerData.ntrkhitsperview[iTrk][2] == TrackerData.ntrkhitsperview[iTrk][1] && TrackerData.ntrkhitsperview[iTrk][2] > TrackerData.ntrkhitsperview[iTrk][0]) TrackerData.trkpidbestplane[iTrk] = 2;
5688  else if(TrackerData.ntrkhitsperview[iTrk][1] == TrackerData.ntrkhitsperview[iTrk][0] && TrackerData.ntrkhitsperview[iTrk][1] > TrackerData.ntrkhitsperview[iTrk][2]) TrackerData.trkpidbestplane[iTrk] = 0;
5689  else if(TrackerData.ntrkhitsperview[iTrk][1] == TrackerData.ntrkhitsperview[iTrk][0] && TrackerData.ntrkhitsperview[iTrk][1] == TrackerData.ntrkhitsperview[iTrk][2]) TrackerData.trkpidbestplane[iTrk] = 2;
5690 
5691  // FIXME - Do i want to add someway to work out the best TPC???....
5692  } // if has calorimetry info
5693 /*
5694  //track truth information
5695  if (fIsMC){
5696  //get the hits on each plane
5697  art::FindManyP<recob::Hit> fmht(trackListHandle[iTracker], evt, fTrackModuleLabel[iTracker]);
5698  std::vector< art::Ptr<recob::Hit> > allHits = fmht.at(iTrk);
5699  std::vector< art::Ptr<recob::Hit> > hits[kNplanes];
5700 
5701  for(size_t ah = 0; ah < allHits.size(); ++ah){
5702 // if ( allHits[ah]->WireID().Plane >= 0 && // always true
5703  if( allHits[ah]->WireID().Plane < 3){
5704  hits[allHits[ah]->WireID().Plane].push_back(allHits[ah]);
5705  }
5706  }
5707  for (size_t ipl = 0; ipl < 3; ++ipl){
5708  double maxe = 0;
5709  HitsBackTrack(clockData, hits[ipl],TrackerData.trkidtruth[iTrk][ipl],TrackerData.trkpurtruth[iTrk][ipl],maxe);
5710  //std::cout<<"\n"<<iTracker<<"\t"<<iTrk<<"\t"<<ipl<<"\t"<<trkidtruth[iTracker][iTrk][ipl]<<"\t"<<trkpurtruth[iTracker][iTrk][ipl]<<"\t"<<maxe;
5711  if (TrackerData.trkidtruth[iTrk][ipl]>0){
5712  const art::Ptr<simb::MCTruth> mc = pi_serv->TrackIdToMCTruth_P(TrackerData.trkidtruth[iTrk][ipl]);
5713  TrackerData.trkorigin[iTrk][ipl] = mc->Origin();
5714  const simb::MCParticle *particle = pi_serv->TrackIdToParticle_P(TrackerData.trkidtruth[iTrk][ipl]);
5715  double tote = 0;
5716  const std::vector<const sim::IDE*> vide=bt_serv->TrackIdToSimIDEs_Ps(TrackerData.trkidtruth[iTrk][ipl]);
5717  for (auto ide: vide) {
5718  tote += ide->energy;
5719  }
5720  TrackerData.trkpdgtruth[iTrk][ipl] = particle->PdgCode();
5721  TrackerData.trkefftruth[iTrk][ipl] = maxe/(tote/kNplanes); //tote include both induction and collection energies
5722  //std::cout<<"\n"<<trkpdgtruth[iTracker][iTrk][ipl]<<"\t"<<trkefftruth[iTracker][iTrk][ipl];
5723  }
5724  }
5725 
5726  double maxe = 0;
5727  HitsBackTrack(clockData, allHits,TrackerData.trkg4id[iTrk],TrackerData.trkpurity[iTrk],maxe);
5728  if (TrackerData.trkg4id[iTrk]>0){
5729  const art::Ptr<simb::MCTruth> mc = pi_serv->TrackIdToMCTruth_P(TrackerData.trkg4id[iTrk]);
5730  TrackerData.trkorig[iTrk] = mc->Origin();
5731  }
5732  if (allHits.size()){
5733  std::vector<art::Ptr<recob::Hit> > all_hits;
5734  art::Handle<std::vector<recob::Hit> > hithandle;
5735  float totenergy = 0;
5736  if (evt.get(allHits[0].id(), hithandle)){
5737  art::fill_ptr_vector(all_hits, hithandle);
5738  for(size_t h = 0; h < all_hits.size(); ++h){
5739 
5740  art::Ptr<recob::Hit> hit = all_hits[h];
5741  std::vector<sim::IDE> ides;
5742  //bt_serv->HitToSimIDEs(hit,ides);
5743  std::vector<sim::TrackIDE> eveIDs = bt_serv->HitToEveTrackIDEs(clockData, hit);
5744 
5745  for(size_t e = 0; e < eveIDs.size(); ++e){
5746  //std::cout<<h<<" "<<e<<" "<<eveIDs[e].trackID<<" "<<eveIDs[e].energy<<" "<<eveIDs[e].energyFrac<<std::endl;
5747  if (eveIDs[e].trackID==TrackerData.trkg4id[iTrk]) totenergy += eveIDs[e].energy;
5748  }
5749  }
5750  }
5751  if (totenergy) TrackerData.trkcompleteness[iTrk] = maxe/totenergy;
5752  }
5753  }//end if (fIsMC)
5754 */
5755  }//end loop over track
5756  //std::cout << "HitIterator: " << HitIterator << std::endl;
5757  }//end loop over track module labels
5758 }// end (fSaveTrackInfo)
5759 
5760  /*trkf::TrackMomentumCalculator trkm;
5761  std::cout<<"\t"<<trkm.GetTrackMomentum(200,2212)<<"\t"<<trkm.GetTrackMomentum(-10, 13)<<"\t"<<trkm.GetTrackMomentum(300,-19)<<"\n";
5762  */
5763 
5764  //Save Vertex information for multiple algorithms
5765  if (fSaveVertexInfo){
5766  for (unsigned int iVertexAlg=0; iVertexAlg < NVertexAlgos; ++iVertexAlg){
5767  AnaRootParserDataStruct::VertexDataStruct& VertexData = fData->GetVertexData(iVertexAlg);
5768 
5769  size_t NVertices = vertexlist[iVertexAlg].size();
5770 
5771  VertexData.SetMaxVertices(std::max(NVertices, (size_t) 1));
5772  VertexData.Clear(); // clear all the data
5773 
5774  VertexData.nvtx = (short) NVertices;
5775 
5776  // now set the tree addresses to the newly allocated memory;
5777  // this creates the tree branches in case they are not there yet
5778  SetVertexAddresses(iVertexAlg);
5779  if (NVertices > VertexData.GetMaxVertices()) {
5780  // got this error? it might be a bug,
5781  // since we are supposed to have allocated enough space to fit all tracks
5782  mf::LogError("AnaRootParser:limits") << "event has " << NVertices
5783  << " " << fVertexModuleLabel[iVertexAlg] << " tracks, only "
5784  << VertexData.GetMaxVertices() << " stored in tree";
5785  }
5786 
5787  for (size_t i = 0; i < NVertices && i < kMaxVertices ; ++i){//loop over hits
5788  VertexData.vtxId[i] = vertexlist[iVertexAlg][i]->ID();
5789  Double_t xyz[3] = {};
5790  vertexlist[iVertexAlg][i] -> XYZ(xyz);
5791  VertexData.vtxx[i] = xyz[0];
5792  VertexData.vtxy[i] = xyz[1];
5793  VertexData.vtxz[i] = xyz[2];
5794 
5795  if (fSavePFParticleInfo) {
5796  auto mapIter = vertexIDtoPFParticleIDMap.find(vertexlist[iVertexAlg][i]->ID());
5797  if (mapIter != vertexIDtoPFParticleIDMap.end()) {
5798  // This vertex has a corresponding PFParticle.
5799  VertexData.vtxhasPFParticle[i] = 1;
5800  VertexData.vtxPFParticleID[i] = mapIter->second;
5801  }
5802  else
5803  VertexData.vtxhasPFParticle[i] = 0;
5804  }
5805 
5806  // find PFParticle ID info
5807  art::FindMany<recob::PFParticle> fmPFParticle(vertexListHandle[iVertexAlg], evt, fPFParticleModuleLabel);
5808  if(fmPFParticle.isValid()) {
5809  std::vector<const recob::PFParticle*> pfparticles = fmPFParticle.at(i);
5810  if(pfparticles.size() > 1)
5811  std::cerr << "Warning: more than one associated PFParticle found for a vertex. Only one stored in tree." << std::endl;
5812  if (pfparticles.size() == 0)
5813  VertexData.vtxhasPFParticle[i] = 0;
5814  else {
5815  VertexData.vtxhasPFParticle[i] = 1;
5816  VertexData.vtxPFParticleID[i] = pfparticles.at(0)->Self();
5817  }
5818  } // fmPFParticle.isValid()
5819  }
5820  }
5821  }
5822 
5823 
5824  //mc truth information
5825  if (fIsMC)
5826  {
5827 
5828  if (fSaveCryInfo)
5829  {
5830 
5831  //store cry (cosmic generator information)
5832  fData->mcevts_truthcry = mclistcry.size();
5833  fData->cry_no_primaries = nCryPrimaries;
5834  //fData->cry_no_primaries;
5835  for(Int_t iPartc = 0; iPartc < mctruthcry->NParticles(); ++iPartc){
5836  const simb::MCParticle& partc(mctruthcry->GetParticle(iPartc));
5837  fData->cry_primaries_pdg[iPartc]=partc.PdgCode();
5838  fData->cry_Eng[iPartc]=partc.E();
5839  fData->cry_Px[iPartc]=partc.Px();
5840  fData->cry_Py[iPartc]=partc.Py();
5841  fData->cry_Pz[iPartc]=partc.Pz();
5842  fData->cry_P[iPartc]=partc.P();
5843  fData->cry_StartPointx[iPartc] = partc.Vx();
5844  fData->cry_StartPointy[iPartc] = partc.Vy();
5845  fData->cry_StartPointz[iPartc] = partc.Vz();
5846  fData->cry_StartPointt[iPartc] = partc.T();
5847  fData->cry_status_code[iPartc]=partc.StatusCode();
5848  fData->cry_mass[iPartc]=partc.Mass();
5849  fData->cry_trackID[iPartc]=partc.TrackId();
5850  fData->cry_ND[iPartc]=partc.NumberDaughters();
5851  fData->cry_mother[iPartc]=partc.Mother();
5852  } // for cry particles
5853  }// end fSaveCryInfo
5854 
5855  // Save the protoDUNE beam generator information
5856  if(fSaveProtoInfo){
5857  fData->proto_no_primaries = nProtoPrimaries;
5858  for(Int_t iPartp = 0; iPartp < nProtoPrimaries; ++iPartp){
5859  const simb::MCParticle& partp(mctruthproto->GetParticle(iPartp));
5860 
5861  fData->proto_isGoodParticle[iPartp] = (partp.Process() == "primary");
5862  fData->proto_vx[iPartp] = partp.Vx();
5863  fData->proto_vy[iPartp] = partp.Vy();
5864  fData->proto_vz[iPartp] = partp.Vz();
5865  fData->proto_t[iPartp] = partp.T();
5866  fData->proto_px[iPartp] = partp.Px();
5867  fData->proto_py[iPartp] = partp.Py();
5868  fData->proto_pz[iPartp] = partp.Pz();
5869  fData->proto_momentum[iPartp] = partp.P();
5870  fData->proto_energy[iPartp] = partp.E();
5871  fData->proto_pdg[iPartp] = partp.PdgCode();
5872  }
5873  }
5874 
5875  //save neutrino interaction information
5876  fData->mcevts_truth = mclist.size();
5877  if (fData->mcevts_truth > 0) //at least one mc record
5878  {
5879  if (fSaveGenieInfo)
5880  {
5881  int neutrino_i = 0;
5882  for(unsigned int iList = 0; (iList < mclist.size()) && (neutrino_i < kMaxTruth) ; ++iList){
5883  if (mclist[iList]->NeutrinoSet()){
5884  fData->nuPDG_truth[neutrino_i] = mclist[iList]->GetNeutrino().Nu().PdgCode();
5885  fData->ccnc_truth[neutrino_i] = mclist[iList]->GetNeutrino().CCNC();
5886  fData->mode_truth[neutrino_i] = mclist[iList]->GetNeutrino().Mode();
5887  fData->Q2_truth[neutrino_i] = mclist[iList]->GetNeutrino().QSqr();
5888  fData->W_truth[neutrino_i] = mclist[iList]->GetNeutrino().W();
5889  fData->X_truth[neutrino_i] = mclist[iList]->GetNeutrino().X();
5890  fData->Y_truth[neutrino_i] = mclist[iList]->GetNeutrino().Y();
5891  fData->hitnuc_truth[neutrino_i] = mclist[iList]->GetNeutrino().HitNuc();
5892  fData->enu_truth[neutrino_i] = mclist[iList]->GetNeutrino().Nu().E();
5893  fData->nuvtxx_truth[neutrino_i] = mclist[iList]->GetNeutrino().Nu().Vx();
5894  fData->nuvtxy_truth[neutrino_i] = mclist[iList]->GetNeutrino().Nu().Vy();
5895  fData->nuvtxz_truth[neutrino_i] = mclist[iList]->GetNeutrino().Nu().Vz();
5896  if (mclist[iList]->GetNeutrino().Nu().P()){
5897  fData->nu_dcosx_truth[neutrino_i] = mclist[iList]->GetNeutrino().Nu().Px()/mclist[iList]->GetNeutrino().Nu().P();
5898  fData->nu_dcosy_truth[neutrino_i] = mclist[iList]->GetNeutrino().Nu().Py()/mclist[iList]->GetNeutrino().Nu().P();
5899  fData->nu_dcosz_truth[neutrino_i] = mclist[iList]->GetNeutrino().Nu().Pz()/mclist[iList]->GetNeutrino().Nu().P();
5900  }
5901  fData->lep_mom_truth[neutrino_i] = mclist[iList]->GetNeutrino().Lepton().P();
5902  if (mclist[iList]->GetNeutrino().Lepton().P()){
5903  fData->lep_dcosx_truth[neutrino_i] = mclist[iList]->GetNeutrino().Lepton().Px()/mclist[iList]->GetNeutrino().Lepton().P();
5904  fData->lep_dcosy_truth[neutrino_i] = mclist[iList]->GetNeutrino().Lepton().Py()/mclist[iList]->GetNeutrino().Lepton().P();
5905  fData->lep_dcosz_truth[neutrino_i] = mclist[iList]->GetNeutrino().Lepton().Pz()/mclist[iList]->GetNeutrino().Lepton().P();
5906  }
5907 
5908  //flux information
5909  //
5910  // Double-check that a simb::MCFlux object is associated with the
5911  // current simb::MCTruth object. For GENIE events, these should
5912  // always accompany each other. Other generators (e.g., MARLEY) may
5913  // create simb::MCTruth objects without corresponding simb::MCFlux
5914  // objects. -- S. Gardiner
5915  /* if (find_mcflux.isValid()) {
5916  auto flux_maybe_ref = find_mcflux.at(iList);
5917  if (flux_maybe_ref.isValid()) {
5918  auto flux_ref = flux_maybe_ref.ref();
5919  fData->vx_flux[neutrino_i] = flux_ref.fvx;
5920  fData->vy_flux[neutrino_i] = flux_ref.fvy;
5921  fData->vz_flux[neutrino_i] = flux_ref.fvz;
5922  fData->pdpx_flux[neutrino_i] = flux_ref.fpdpx;
5923  fData->pdpy_flux[neutrino_i] = flux_ref.fpdpy;
5924  fData->pdpz_flux[neutrino_i] = flux_ref.fpdpz;
5925  fData->ppdxdz_flux[neutrino_i] = flux_ref.fppdxdz;
5926  fData->ppdydz_flux[neutrino_i] = flux_ref.fppdydz;
5927  fData->pppz_flux[neutrino_i] = flux_ref.fpppz;
5928 
5929  fData->ptype_flux[neutrino_i] = flux_ref.fptype;
5930  fData->ppvx_flux[neutrino_i] = flux_ref.fppvx;
5931  fData->ppvy_flux[neutrino_i] = flux_ref.fppvy;
5932  fData->ppvz_flux[neutrino_i] = flux_ref.fppvz;
5933  fData->muparpx_flux[neutrino_i] = flux_ref.fmuparpx;
5934  fData->muparpy_flux[neutrino_i] = flux_ref.fmuparpy;
5935  fData->muparpz_flux[neutrino_i] = flux_ref.fmuparpz;
5936  fData->mupare_flux[neutrino_i] = flux_ref.fmupare;
5937 
5938  fData->tgen_flux[neutrino_i] = flux_ref.ftgen;
5939  fData->tgptype_flux[neutrino_i] = flux_ref.ftgptype;
5940  fData->tgppx_flux[neutrino_i] = flux_ref.ftgppx;
5941  fData->tgppy_flux[neutrino_i] = flux_ref.ftgppy;
5942  fData->tgppz_flux[neutrino_i] = flux_ref.ftgppz;
5943  fData->tprivx_flux[neutrino_i] = flux_ref.ftprivx;
5944  fData->tprivy_flux[neutrino_i] = flux_ref.ftprivy;
5945  fData->tprivz_flux[neutrino_i] = flux_ref.ftprivz;
5946 
5947  fData->dk2gen_flux[neutrino_i] = flux_ref.fdk2gen;
5948  fData->gen2vtx_flux[neutrino_i] = flux_ref.fgen2vtx;
5949 
5950  fData->tpx_flux[neutrino_i] = flux_ref.ftpx;
5951  fData->tpy_flux[neutrino_i] = flux_ref.ftpy;
5952  fData->tpz_flux[neutrino_i] = flux_ref.ftpz;
5953  fData->tptype_flux[neutrino_i] = flux_ref.ftptype;
5954  } // flux_maybe_ref.isValid()
5955  } // find_mcflux.isValid() */
5956  neutrino_i++;
5957  }//mclist is NeutrinoSet()
5958  }//loop over mclist
5959 
5960  if (mctruth->NeutrinoSet()){
5961  //genie particles information
5962  fData->genie_no_primaries = mctruth->NParticles();
5963 
5964  size_t StoreParticles = std::min((size_t) fData->genie_no_primaries, fData->GetMaxGeniePrimaries());
5965  if (fData->genie_no_primaries > (int) StoreParticles) {
5966  // got this error? it might be a bug,
5967  // since the structure should have enough room for everything
5968  mf::LogError("AnaRootParser:limits") << "event has "
5969  << fData->genie_no_primaries << " MC particles, only "
5970  << StoreParticles << " stored in tree";
5971  }
5972  for(size_t iPart = 0; iPart < StoreParticles; ++iPart){
5973  const simb::MCParticle& part(mctruth->GetParticle(iPart));
5974  fData->genie_primaries_pdg[iPart]=part.PdgCode();
5975  fData->genie_Eng[iPart]=part.E();
5976  fData->genie_Px[iPart]=part.Px();
5977  fData->genie_Py[iPart]=part.Py();
5978  fData->genie_Pz[iPart]=part.Pz();
5979  fData->genie_P[iPart]=part.P();
5980  fData->genie_status_code[iPart]=part.StatusCode();
5981  fData->genie_mass[iPart]=part.Mass();
5982  fData->genie_trackID[iPart]=part.TrackId();
5983  fData->genie_ND[iPart]=part.NumberDaughters();
5984  fData->genie_mother[iPart]=part.Mother();
5985  } // for particle
5986  //const simb::MCNeutrino& nu(mctruth->GetNeutrino());
5987  } //if neutrino set
5988  }// end (fSaveGenieInfo)
5989 
5990  //Extract MC Shower information and fill the Shower branches
5991  if (fSaveMCShowerInfo)
5992  {
5993  fData->no_mcshowers = nMCShowers;
5994  size_t shwr = 0;
5995  for(std::vector<sim::MCShower>::const_iterator imcshwr = mcshowerh->begin();
5996  imcshwr != mcshowerh->end(); ++imcshwr) {
5997  const sim::MCShower& mcshwr = *imcshwr;
5998  fData->mcshwr_origin[shwr] = mcshwr.Origin();
5999  fData->mcshwr_pdg[shwr] = mcshwr.PdgCode();
6000  fData->mcshwr_TrackId[shwr] = mcshwr.TrackID();
6001  fData->mcshwr_Process[shwr] = mcshwr.Process();
6002  fData->mcshwr_startX[shwr] = mcshwr.Start().X();
6003  fData->mcshwr_startY[shwr] = mcshwr.Start().Y();
6004  fData->mcshwr_startZ[shwr] = mcshwr.Start().Z();
6005  fData->mcshwr_endX[shwr] = mcshwr.End().X();
6006  fData->mcshwr_endY[shwr] = mcshwr.End().Y();
6007  fData->mcshwr_endZ[shwr] = mcshwr.End().Z();
6008  if (mcshwr.DetProfile().E()!= 0){
6009  fData->mcshwr_isEngDeposited[shwr] = 1;
6010  fData->mcshwr_CombEngX[shwr] = mcshwr.DetProfile().X();
6011  fData->mcshwr_CombEngY[shwr] = mcshwr.DetProfile().Y();
6012  fData->mcshwr_CombEngZ[shwr] = mcshwr.DetProfile().Z();
6013  fData->mcshwr_CombEngPx[shwr] = mcshwr.DetProfile().Px();
6014  fData->mcshwr_CombEngPy[shwr] = mcshwr.DetProfile().Py();
6015  fData->mcshwr_CombEngPz[shwr] = mcshwr.DetProfile().Pz();
6016  fData->mcshwr_CombEngE[shwr] = mcshwr.DetProfile().E();
6017  fData->mcshwr_dEdx[shwr] = mcshwr.dEdx();
6018  fData->mcshwr_StartDirX[shwr] = mcshwr.StartDir().X();
6019  fData->mcshwr_StartDirY[shwr] = mcshwr.StartDir().Y();
6020  fData->mcshwr_StartDirZ[shwr] = mcshwr.StartDir().Z();
6021  }
6022  else
6023  fData->mcshwr_isEngDeposited[shwr] = 0;
6024  fData->mcshwr_Motherpdg[shwr] = mcshwr.MotherPdgCode();
6025  fData->mcshwr_MotherTrkId[shwr] = mcshwr.MotherTrackID();
6026  fData->mcshwr_MotherProcess[shwr] = mcshwr.MotherProcess();
6027  fData->mcshwr_MotherstartX[shwr] = mcshwr.MotherStart().X();
6028  fData->mcshwr_MotherstartY[shwr] = mcshwr.MotherStart().Y();
6029  fData->mcshwr_MotherstartZ[shwr] = mcshwr.MotherStart().Z();
6030  fData->mcshwr_MotherendX[shwr] = mcshwr.MotherEnd().X();
6031  fData->mcshwr_MotherendY[shwr] = mcshwr.MotherEnd().Y();
6032  fData->mcshwr_MotherendZ[shwr] = mcshwr.MotherEnd().Z();
6033  fData->mcshwr_Ancestorpdg[shwr] = mcshwr.AncestorPdgCode();
6034  fData->mcshwr_AncestorTrkId[shwr] = mcshwr.AncestorTrackID();
6035  fData->mcshwr_AncestorProcess[shwr] = mcshwr.AncestorProcess();
6036  fData->mcshwr_AncestorstartX[shwr] = mcshwr.AncestorStart().X();
6037  fData->mcshwr_AncestorstartY[shwr] = mcshwr.AncestorStart().Y();
6038  fData->mcshwr_AncestorstartZ[shwr] = mcshwr.AncestorStart().Z();
6039  fData->mcshwr_AncestorendX[shwr] = mcshwr.AncestorEnd().X();
6040  fData->mcshwr_AncestorendY[shwr] = mcshwr.AncestorEnd().Y();
6041  fData->mcshwr_AncestorendZ[shwr] = mcshwr.AncestorEnd().Z();
6042  ++shwr;
6043  }
6044  fData->mcshwr_Process.resize(shwr);
6045  fData->mcshwr_MotherProcess.resize(shwr);
6046  fData->mcshwr_AncestorProcess.resize(shwr);
6047  }//End if (fSaveMCShowerInfo){
6048 
6049  //Extract MC Track information and fill the Shower branches
6050  if (fSaveMCTrackInfo)
6051  {
6052  fData->no_mctracks = nMCTracks;
6053  size_t trk = 0;
6054  for(std::vector<sim::MCTrack>::const_iterator imctrk = mctrackh->begin();imctrk != mctrackh->end(); ++imctrk) {
6055  const sim::MCTrack& mctrk = *imctrk;
6056  TLorentzVector tpcstart, tpcend, tpcmom;
6057  double plen = driftedLength(detProp, mctrk, tpcstart, tpcend, tpcmom);
6058  fData->mctrk_origin[trk] = mctrk.Origin();
6059  fData->mctrk_pdg[trk] = mctrk.PdgCode();
6060  fData->mctrk_TrackId[trk] = mctrk.TrackID();
6061  fData->mctrk_Process[trk] = mctrk.Process();
6062  fData->mctrk_startX[trk] = mctrk.Start().X();
6063  fData->mctrk_startY[trk] = mctrk.Start().Y();
6064  fData->mctrk_startZ[trk] = mctrk.Start().Z();
6065  fData->mctrk_endX[trk] = mctrk.End().X();
6066  fData->mctrk_endY[trk] = mctrk.End().Y();
6067  fData->mctrk_endZ[trk] = mctrk.End().Z();
6068  fData->mctrk_Motherpdg[trk] = mctrk.MotherPdgCode();
6069  fData->mctrk_MotherTrkId[trk] = mctrk.MotherTrackID();
6070  fData->mctrk_MotherProcess[trk] = mctrk.MotherProcess();
6071  fData->mctrk_MotherstartX[trk] = mctrk.MotherStart().X();
6072  fData->mctrk_MotherstartY[trk] = mctrk.MotherStart().Y();
6073  fData->mctrk_MotherstartZ[trk] = mctrk.MotherStart().Z();
6074  fData->mctrk_MotherendX[trk] = mctrk.MotherEnd().X();
6075  fData->mctrk_MotherendY[trk] = mctrk.MotherEnd().Y();
6076  fData->mctrk_MotherendZ[trk] = mctrk.MotherEnd().Z();
6077  fData->mctrk_Ancestorpdg[trk] = mctrk.AncestorPdgCode();
6078  fData->mctrk_AncestorTrkId[trk] = mctrk.AncestorTrackID();
6079  fData->mctrk_AncestorProcess[trk] = mctrk.AncestorProcess();
6080  fData->mctrk_AncestorstartX[trk] = mctrk.AncestorStart().X();
6081  fData->mctrk_AncestorstartY[trk] = mctrk.AncestorStart().Y();
6082  fData->mctrk_AncestorstartZ[trk] = mctrk.AncestorStart().Z();
6083  fData->mctrk_AncestorendX[trk] = mctrk.AncestorEnd().X();
6084  fData->mctrk_AncestorendY[trk] = mctrk.AncestorEnd().Y();
6085  fData->mctrk_AncestorendZ[trk] = mctrk.AncestorEnd().Z();
6086 
6087  fData->mctrk_len_drifted[trk] = plen;
6088 
6089  if (plen != 0){
6090  fData->mctrk_startX_drifted[trk] = tpcstart.X();
6091  fData->mctrk_startY_drifted[trk] = tpcstart.Y();
6092  fData->mctrk_startZ_drifted[trk] = tpcstart.Z();
6093  fData->mctrk_endX_drifted[trk] = tpcend.X();
6094  fData->mctrk_endY_drifted[trk] = tpcend.Y();
6095  fData->mctrk_endZ_drifted[trk] = tpcend.Z();
6096  fData->mctrk_p_drifted[trk] = tpcmom.Vect().Mag();
6097  fData->mctrk_px_drifted[trk] = tpcmom.X();
6098  fData->mctrk_py_drifted[trk] = tpcmom.Y();
6099  fData->mctrk_pz_drifted[trk] = tpcmom.Z();
6100  }
6101  ++trk;
6102  }
6103 
6104  fData->mctrk_Process.resize(trk);
6105  fData->mctrk_MotherProcess.resize(trk);
6106  fData->mctrk_AncestorProcess.resize(trk);
6107  }//End if (fSaveMCTrackInfo){
6108 
6109 
6110  //Photon particles information
6111  if (fSavePhotonInfo)
6112  {
6113  int photoncounter=0;
6114  for ( auto const& pmt : (*photonHandle) )
6115  {
6116  std::map<int, int> PhotonsMap = pmt.DetectedPhotons;
6117 
6118  for(auto itphoton = PhotonsMap.begin(); itphoton!= PhotonsMap.end(); itphoton++)
6119  {
6120  for(int iphotonatthistime = 0; iphotonatthistime < itphoton->second ; iphotonatthistime++)
6121  {
6122  fData->photons_time[photoncounter]=itphoton->first;
6123  fData->photons_channel[photoncounter]=pmt.OpChannel;
6124  photoncounter++;
6125  }
6126  }
6127  }
6128  fData->numberofphotons=photoncounter;
6129  }
6130 
6131  //Generator particles information
6132  if (fSaveGeneratorInfo)
6133  {
6134  const sim::ParticleList& plist = pi_serv->ParticleList();
6135 
6136  size_t generator_particle=0;
6137  sim::ParticleList::const_iterator itPart = plist.begin(),
6138  pend = plist.end(); // iterator to pairs (track id, particle)
6139 
6140  for(size_t iPart = 0; (iPart < plist.size()) && (itPart != pend); ++iPart){
6141 
6142  const simb::MCParticle* pPart = (itPart++)->second;
6143  if (!pPart) {
6145  << "GEANT particle #" << iPart << " returned a null pointer";
6146  }
6147 
6148  if (iPart < fData->GetMaxGeneratorparticles()) {
6149 
6150  std::string pri("primary");
6151  if( pPart->Mother() == 0 && pPart->Process() == pri )
6152  {
6153  fData->TrackId[generator_particle]=pPart->TrackId();
6154  fData->pdg[generator_particle]=pPart->PdgCode();
6155  fData->status[generator_particle] = pPart->StatusCode();
6156  fData->Eng[generator_particle]=pPart->E();
6157  fData->Mass[generator_particle]=pPart->Mass();
6158  fData->Px[generator_particle]=pPart->Px();
6159  fData->Py[generator_particle]=pPart->Py();
6160  fData->Pz[generator_particle]=pPart->Pz();
6161  fData->P[generator_particle]=pPart->Momentum().Vect().Mag();
6162  fData->StartPointx[generator_particle]=pPart->Vx();
6163  fData->StartPointy[generator_particle]=pPart->Vy();
6164  fData->StartPointz[generator_particle]=pPart->Vz();
6165  fData->StartT[generator_particle] = pPart->T();
6166 
6167  TVector3 momentum_start_flipped;
6168  momentum_start_flipped.SetXYZ(pPart->Pz(), pPart->Py(), pPart->Px());
6169 
6170  fData->theta[generator_particle] = (180.0/3.14159)*momentum_start_flipped.Theta();
6171  fData->phi[generator_particle] = (180.0/3.14159)*momentum_start_flipped.Phi();
6172  }
6173  ++generator_particle;
6174  }
6175  else if (iPart == fData->GetMaxGeneratorparticles()) {
6176  // got this error? it might be a bug,
6177  // since the structure should have enough room for everything
6178  mf::LogError("AnaRootParser:limits") << "event has "
6179  << plist.size() << " MC particles, only "
6180  << fData->GetMaxGeneratorparticles() << " will be stored in tree";
6181  }
6182  } // for particles
6183  fData->generator_list_size = generator_particle;
6184  fData->processname.resize(generator_particle);
6185  MF_LOG_DEBUG("AnaRootParser")
6186  << "Counted "
6187  << fData->generator_list_size << " Generator particles";
6188  }//fSaveGeneratorInfo
6189 
6190 
6191 
6192 
6193  //GEANT particles information
6194  if (fSaveGeantInfo)
6195  {
6196 
6197  const sim::ParticleList& plist = pi_serv->ParticleList();
6198 
6199  std::string pri("primary");
6200  int primary=0;
6201  int active = 0;
6202  size_t geant_particle=0;
6203  sim::ParticleList::const_iterator itPart = plist.begin(),
6204  pend = plist.end(); // iterator to pairs (track id, particle)
6205 
6206  // helper map track ID => index
6207  std::map<int, size_t> TrackIDtoIndex;
6208  std::vector<int> gpdg;
6209  std::vector<int> gmother;
6210  for(size_t iPart = 0; (iPart < plist.size()) && (itPart != pend); ++iPart){
6211  const simb::MCParticle* pPart = (itPart++)->second;
6212  if (!pPart) {
6214  << "GEANT particle #" << iPart << " returned a null pointer";
6215  }
6216 
6217  bool isPrimary = pPart->Process() == pri;
6218  int TrackID = pPart->TrackId();
6219  TrackIDtoIndex.emplace(TrackID, iPart);
6220  gpdg.push_back(pPart->PdgCode());
6221  gmother.push_back(pPart->Mother());
6222  if (iPart < fData->GetMaxGEANTparticles()) {
6223 // if (pPart->E()<fG4minE&&(!isPrimary)) continue;
6224  if (isPrimary) ++primary;
6225 
6226  TLorentzVector mcstart, mcend;
6227  unsigned int pstarti, pendi;
6228  double plen = length(*pPart, mcstart, mcend, pstarti, pendi);
6229  bool isActive = plen != 0;
6230 
6231 // TLorentzVector mcstartdrifted, mcenddrifted;
6232 // unsigned int pstartdriftedi, penddriftedi;
6233 // double plendrifted = driftedLength(*pPart, mcstartdrifted, mcenddrifted, pstartdriftedi, penddriftedi);
6234 // bool isDrifted = plendrifted!= 0;
6235 
6236  if(fLogLevel >= 3)
6237  {
6238  std::cout << "pPart->TrackId():" << pPart->TrackId() << std::endl;
6239  std::cout << "pPart->Mother():" << pPart->Mother() << std::endl;
6240  std::cout << "pPart->PdgCode():" << pPart->PdgCode() << std::endl;
6241  std::cout << std::endl;
6242  }
6243 
6244 
6245  fData->process_primary[geant_particle] = int(isPrimary);
6246  fData->processname[geant_particle]= pPart->Process();
6247  fData->Mother[geant_particle]=pPart->Mother();
6248  fData->TrackId[geant_particle]=pPart->TrackId();
6249  fData->pdg[geant_particle]=pPart->PdgCode();
6250  fData->status[geant_particle] = pPart->StatusCode();
6251  fData->Eng[geant_particle]=pPart->E();
6252  fData->EndE[geant_particle]=pPart->EndE();
6253  fData->Mass[geant_particle]=pPart->Mass();
6254  fData->Px[geant_particle]=pPart->Px();
6255  fData->Py[geant_particle]=pPart->Py();
6256  fData->Pz[geant_particle]=pPart->Pz();
6257  fData->P[geant_particle]=pPart->Momentum().Vect().Mag();
6258  fData->StartPointx[geant_particle]=pPart->Vx();
6259  fData->StartPointy[geant_particle]=pPart->Vy();
6260  fData->StartPointz[geant_particle]=pPart->Vz();
6261  fData->StartT[geant_particle] = pPart->T();
6262  fData->EndPointx[geant_particle]=pPart->EndPosition()[0];
6263  fData->EndPointy[geant_particle]=pPart->EndPosition()[1];
6264  fData->EndPointz[geant_particle]=pPart->EndPosition()[2];
6265  fData->EndT[geant_particle] = pPart->EndT();
6266 
6267  fData->NTrajectoryPointsPerParticle[geant_particle] = pPart->NumberTrajectoryPoints();
6268 
6269  //fData->theta[geant_particle] = pPart->Momentum().Theta();
6270  //fData->phi[geant_particle] = pPart->Momentum().Phi();
6271  //Change definition of theta and phi (swap x and z coordinate since x is "up" in dual phase)
6272  TVector3 momentum_start_flipped;
6273  momentum_start_flipped.SetXYZ(pPart->Pz(), pPart->Py(), pPart->Px());
6274 
6275  fData->theta[geant_particle] = (180.0/3.14159)*momentum_start_flipped.Theta();
6276  fData->phi[geant_particle] = (180.0/3.14159)*momentum_start_flipped.Phi();
6277 
6278  fData->theta_xz[geant_particle] = std::atan2(pPart->Px(), pPart->Pz());
6279  fData->theta_yz[geant_particle] = std::atan2(pPart->Py(), pPart->Pz());
6280 // fData->pathlen_drifted[geant_particle] = plendrifted;
6281  fData->NumberDaughters[geant_particle]=pPart->NumberDaughters();
6282  fData->inTPCActive[geant_particle] = int(isActive);
6283 // fData->inTPCDrifted[geant_particle] = int(isDrifted);
6284  art::Ptr<simb::MCTruth> const& mc_truth = pi_serv->ParticleToMCTruth_P(pPart);
6285  if (mc_truth){
6286  fData->origin[geant_particle] = mc_truth->Origin();
6287  fData->MCTruthIndex[geant_particle] = mc_truth.key();
6288  }
6289 
6290  if (isActive && fSaveGeantInAVInfo){
6291  fData->pathlen_tpcAV[active] = plen;
6292  fData->TrackId_tpcAV[active] = pPart->TrackId();
6293  fData->PDGCode_tpcAV[active] = pPart->PdgCode();
6294 
6295  fData->StartPointx_tpcAV[active] = mcstart.X();
6296  fData->StartPointy_tpcAV[active] = mcstart.Y();
6297  fData->StartPointz_tpcAV[active] = mcstart.Z();
6298  fData->StartT_tpcAV[active] = mcstart.T();
6299  fData->StartE_tpcAV[active] = pPart->E(pstarti);
6300  fData->StartP_tpcAV[active] = pPart->P(pstarti);
6301  fData->StartPx_tpcAV[active] = pPart->Px(pstarti);
6302  fData->StartPy_tpcAV[active] = pPart->Py(pstarti);
6303  fData->StartPz_tpcAV[active] = pPart->Pz(pstarti);
6304  fData->EndPointx_tpcAV[active] = mcend.X();
6305  fData->EndPointy_tpcAV[active] = mcend.Y();
6306  fData->EndPointz_tpcAV[active] = mcend.Z();
6307  fData->EndT_tpcAV[active] = mcend.T();
6308  fData->EndE_tpcAV[active] = pPart->E(pendi);
6309  fData->EndP_tpcAV[active] = pPart->P(pendi);
6310  fData->EndPx_tpcAV[active] = pPart->Px(pendi);
6311  fData->EndPy_tpcAV[active] = pPart->Py(pendi);
6312  fData->EndPz_tpcAV[active] = pPart->Pz(pendi);
6313 
6314  //Change definition of theta and phi (swap x and z coordinate since x is "up" in dual phase)
6315  TVector3 momentum_start_tpcAv_flipped;
6316  momentum_start_tpcAv_flipped.SetXYZ(pPart->Pz(pstarti), pPart->Py(pstarti), pPart->Px(pstarti));
6317  TVector3 momentum_end_tpcAv_flipped;
6318  momentum_end_tpcAv_flipped.SetXYZ(pPart->Pz(pendi), pPart->Py(pendi), pPart->Px(pendi));
6319 
6320  fData->thetastart_tpcAV[active] = (180.0/3.14159)*momentum_start_tpcAv_flipped.Theta();
6321  fData->phistart_tpcAV[active] = (180.0/3.14159)*momentum_start_tpcAv_flipped.Phi();
6322 
6323  fData->thetaend_tpcAV[active] = (180.0/3.14159)*momentum_end_tpcAv_flipped.Theta();
6324  fData->phiend_tpcAV[active] = (180.0/3.14159)*momentum_end_tpcAv_flipped.Phi();
6325 
6326  active++;
6327  }
6328 
6329 /*
6330  if (isDrifted){
6331  fData->StartPointx_drifted[geant_particle] = mcstartdrifted.X();
6332  fData->StartPointy_drifted[geant_particle] = mcstartdrifted.Y();
6333  fData->StartPointz_drifted[geant_particle] = mcstartdrifted.Z();
6334  fData->StartT_drifted[geant_particle] = mcstartdrifted.T();
6335  fData->StartE_drifted[geant_particle] = pPart->E(pstartdriftedi);
6336  fData->StartP_drifted[geant_particle] = pPart->P(pstartdriftedi);
6337  fData->StartPx_drifted[geant_particle] = pPart->Px(pstartdriftedi);
6338  fData->StartPy_drifted[geant_particle] = pPart->Py(pstartdriftedi);
6339  fData->StartPz_drifted[geant_particle] = pPart->Pz(pstartdriftedi);
6340  fData->EndPointx_drifted[geant_particle] = mcenddrifted.X();
6341  fData->EndPointy_drifted[geant_particle] = mcenddrifted.Y();
6342  fData->EndPointz_drifted[geant_particle] = mcenddrifted.Z();
6343  fData->EndT_drifted[geant_particle] = mcenddrifted.T();
6344  fData->EndE_drifted[geant_particle] = pPart->E(penddriftedi);
6345  fData->EndP_drifted[geant_particle] = pPart->P(penddriftedi);
6346  fData->EndPx_drifted[geant_particle] = pPart->Px(penddriftedi);
6347  fData->EndPy_drifted[geant_particle] = pPart->Py(penddriftedi);
6348  fData->EndPz_drifted[geant_particle] = pPart->Pz(penddriftedi);
6349  }
6350 */
6351  //access auxiliary detector parameters
6352  if (fSaveAuxDetInfo) {
6353  unsigned short nAD = 0; // number of cells that particle hit
6354 
6355  // find deposit of this particle in each of the detector cells
6356  for (const sim::AuxDetSimChannel* c: fAuxDetSimChannels) {
6357 
6358  // find if this cell has a contribution (IDE) from this particle,
6359  // and which one
6360  const std::vector<sim::AuxDetIDE>& setOfIDEs = c->AuxDetIDEs();
6361  // using a C++ "lambda" function here; this one:
6362  // - sees only TrackID from the current scope
6363  // - takes one parameter: the AuxDetIDE to be tested
6364  // - returns if that IDE belongs to the track we are looking for
6366  = std::find_if(
6367  setOfIDEs.begin(), setOfIDEs.end(),
6368  [TrackID](const sim::AuxDetIDE& IDE){ return IDE.trackID == TrackID; }
6369  );
6370  if (iIDE == setOfIDEs.end()) continue;
6371 
6372  // now iIDE points to the energy released by the track #i (TrackID)
6373 
6374  // look for IDE with matching trackID
6375  // find trackIDs stored in setOfIDEs with the same trackID, but negative,
6376  // this is an untracked particle who's energy should be added as deposited by this original trackID
6377  float totalE = 0.; // total energy deposited around by the GEANT particle in this cell
6378  for(const auto& adtracks: setOfIDEs) {
6379  if( fabs(adtracks.trackID) == TrackID )
6380  totalE += adtracks.energyDeposited;
6381  } // for
6382 
6383  // fill the structure
6384  if (nAD < kMaxAuxDets) {
6385  fData->AuxDetID[geant_particle][nAD] = c->AuxDetID();
6386  fData->entryX[geant_particle][nAD] = iIDE->entryX;
6387  fData->entryY[geant_particle][nAD] = iIDE->entryY;
6388  fData->entryZ[geant_particle][nAD] = iIDE->entryZ;
6389  fData->entryT[geant_particle][nAD] = iIDE->entryT;
6390  fData->exitX[geant_particle][nAD] = iIDE->exitX;
6391  fData->exitY[geant_particle][nAD] = iIDE->exitY;
6392  fData->exitZ[geant_particle][nAD] = iIDE->exitZ;
6393  fData->exitT[geant_particle][nAD] = iIDE->exitT;
6394  fData->exitPx[geant_particle][nAD] = iIDE->exitMomentumX;
6395  fData->exitPy[geant_particle][nAD] = iIDE->exitMomentumY;
6396  fData->exitPz[geant_particle][nAD] = iIDE->exitMomentumZ;
6397  fData->CombinedEnergyDep[geant_particle][nAD] = totalE;
6398  }
6399  ++nAD;
6400  } // for aux det sim channels
6401  fData->NAuxDets[geant_particle] = nAD;
6402 
6403  if (nAD > kMaxAuxDets) {
6404  // got this error? consider increasing kMaxAuxDets
6405  mf::LogError("AnaRootParser:limits")
6406  << "particle #" << iPart
6407  << " touches " << nAD << " auxiliary detector cells, only "
6408  << kMaxAuxDets << " of them are saved in the tree";
6409  } // if too many detector cells
6410  } // if (fSaveAuxDetInfo)
6411 
6412  ++geant_particle;
6413  }
6414  else if (iPart == fData->GetMaxGEANTparticles()) {
6415  // got this error? it might be a bug,
6416  // since the structure should have enough room for everything
6417  mf::LogError("AnaRootParser:limits") << "event has "
6418  << plist.size() << " MC particles, only "
6419  << fData->GetMaxGEANTparticles() << " will be stored in tree";
6420  }
6421  } // for particles
6422 
6423  fData->geant_list_size_in_tpcAV = active;
6424  fData->no_primaries = primary;
6425  fData->geant_list_size = geant_particle;
6426  fData->processname.resize(geant_particle);
6427  MF_LOG_DEBUG("AnaRootParser")
6428  << "Counted "
6429  << fData->geant_list_size << " GEANT particles ("
6430  << fData->geant_list_size_in_tpcAV << " in AV), "
6431  << fData->no_primaries << " primaries, "
6432  << fData->genie_no_primaries << " GENIE particles";
6433 
6434  FillWith(fData->MergedId, 0);
6435 
6436  // for each particle, consider all the direct ancestors with the same
6437  // PDG ID, and mark them as belonging to the same "group"
6438  // (having the same MergedId)
6439 
6440 
6441  int currentMergedId = 1;
6442  for(size_t iPart = 0; iPart < geant_particle; ++iPart){
6443  // if the particle already belongs to a group, don't bother
6444  if (fData->MergedId[iPart]) continue;
6445  // the particle starts its own group
6446  fData->MergedId[iPart] = currentMergedId;
6447  int currentMotherTrackId = fData->Mother[iPart];
6448  while (currentMotherTrackId > 0) {
6449  if (TrackIDtoIndex.find(currentMotherTrackId)==TrackIDtoIndex.end()) break;
6450  unsigned int gindex = TrackIDtoIndex[currentMotherTrackId];
6451  if (gindex>=plist.size()) break;
6452  // if the mother particle is of a different type,
6453  // don't bother with iPart ancestry any further
6454  if (gpdg[gindex]!=fData->pdg[iPart]) break;
6455  if (TrackIDtoIndex.find(currentMotherTrackId)!=TrackIDtoIndex.end()){
6456  unsigned int igeantMother = TrackIDtoIndex[currentMotherTrackId];
6457  if (igeantMother<geant_particle){
6458  fData->MergedId[igeantMother] = currentMergedId;
6459  }
6460  }
6461  currentMotherTrackId = gmother[gindex];
6462  }
6463  ++currentMergedId;
6464  }// for merging check
6465 
6466  } // if (fSaveGeantInfo)
6467 
6468  //GEANT trajectory information
6470  {
6471  const sim::ParticleList& plist = pi_serv->ParticleList();
6472  sim::ParticleList::const_iterator itPart = plist.begin(),
6473  pend = plist.end(); // iterator to pairs (track id, particle)
6474  int trajpointcounter = 0;
6475 
6476  for(size_t iPart = 0; (iPart < plist.size()) && (itPart != pend); ++iPart)
6477  {
6478  const simb::MCParticle* pPart = (itPart++)->second;
6479  if (!pPart)
6480  {
6482  << "GEANT particle #" << iPart << " returned a null pointer";
6483  }
6484 
6485  unsigned int numberTrajectoryPoints = pPart->NumberTrajectoryPoints();
6486  for(unsigned int trajpoint=0; trajpoint < numberTrajectoryPoints; ++trajpoint)
6487  {
6488  const TLorentzVector& trajpointPosition= pPart->Position(trajpoint);
6489  //const TLorentzVector& trajpointMomentum= pPart->Momentum(trajpoint);
6490 
6491  fData->TrajTrackId[trajpointcounter] = pPart->TrackId();
6492  fData->TrajPDGCode[trajpointcounter] = pPart->PdgCode();
6493 
6494  fData->TrajX[trajpointcounter] = trajpointPosition.X();
6495  fData->TrajY[trajpointcounter] = trajpointPosition.Y();
6496  fData->TrajZ[trajpointcounter] = trajpointPosition.Z();
6497  fData->TrajT[trajpointcounter] = pPart->T(trajpoint);
6498  fData->TrajE[trajpointcounter] = pPart->E(trajpoint);
6499  fData->TrajP[trajpointcounter] = pPart->P(trajpoint);
6500  fData->TrajPx[trajpointcounter] = pPart->Px(trajpoint);
6501  fData->TrajPy[trajpointcounter] = pPart->Py(trajpoint);
6502  fData->TrajPz[trajpointcounter] = pPart->Pz(trajpoint);
6503 
6504  TVector3 trajpointMomentum_flipped;
6505  trajpointMomentum_flipped.SetXYZ(pPart->Pz(trajpoint), pPart->Py(trajpoint), pPart->Px(trajpoint));
6506 
6507  fData->TrajTheta[trajpointcounter] = (180.0/3.14159)*trajpointMomentum_flipped.Theta();
6508  fData->TrajPhi[trajpointcounter] = (180.0/3.14159)*trajpointMomentum_flipped.Phi();
6509 
6510  if(fLogLevel >= 4)
6511  {
6512  std::cout << std::endl;
6513  std::cout << "trajpointcounter: " << trajpointcounter << std::endl;
6514  std::cout << "fData->TrajTrackId[trajpointcounter]: " << fData->TrajTrackId[trajpointcounter] << std::endl;
6515  std::cout << "fData->TrajPDGCode[trajpointcounter]: " << fData->TrajPDGCode[trajpointcounter] << std::endl;
6516  std::cout << "fData->TrajX[trajpointcounter]: " << fData->TrajX[trajpointcounter] << std::endl;
6517  std::cout << "fData->TrajY[trajpointcounter]: " << fData->TrajY[trajpointcounter] << std::endl;
6518  std::cout << "fData->TrajZ[trajpointcounter]: " << fData->TrajZ[trajpointcounter] << std::endl;
6519  std::cout << "fData->TrajT[trajpointcounter]: " << fData->TrajT[trajpointcounter] << std::endl;
6520  std::cout << "fData->TrajE[trajpointcounter]: " << fData->TrajE[trajpointcounter] << std::endl;
6521  std::cout << "fData->TrajP[trajpointcounter]: " << fData->TrajP[trajpointcounter] << std::endl;
6522  std::cout << "fData->TrajPx[trajpointcounter]: " << fData->TrajPx[trajpointcounter] << std::endl;
6523  std::cout << "fData->TrajPy[trajpointcounter]: " << fData->TrajPy[trajpointcounter] << std::endl;
6524  std::cout << "fData->TrajPz[trajpointcounter]: " << fData->TrajPz[trajpointcounter] << std::endl;
6525  std::cout << "fData->TrajTheta[trajpointcounter]: " << fData->TrajTheta[trajpointcounter] << std::endl;
6526  std::cout << "fData->TrajPhi[trajpointcounter]: " << fData->TrajPhi[trajpointcounter] << std::endl;
6527  }
6528 
6529  trajpointcounter++;
6530  }
6531  } // for particles
6532 
6533  fData->geant_trajectory_size = trajpointcounter;
6534  }// if (fSaveGeantTrajectoryInfo)
6535 
6536 
6538  {
6539  fData->simenergydeposit_size = nSimEnergyDepositsTPCActive;
6540  fData->particleswithsimenergydeposit_size = nParticlesWithSimEnergyDepositsTPCActive;
6541 
6542  // Find particle ID's for each particle with sim energy deposit in this event
6543  int particlewithsedit=0;
6544  for(int sedavit = 0; sedavit < nSimEnergyDepositsTPCActive; sedavit++)
6545  {
6546  if (std::find(fData->ParticleIDSimEnergyDepositsTPCActivePerParticle.begin(), fData->ParticleIDSimEnergyDepositsTPCActivePerParticle.end(), energyDepositTPCActivelist[sedavit]->TrackID()) == fData->ParticleIDSimEnergyDepositsTPCActivePerParticle.end() ) //check if current particle ID is already in the vector. if true: not in vector
6547  {
6548  fData->ParticleIDSimEnergyDepositsTPCActivePerParticle[particlewithsedit] = energyDepositTPCActivelist[sedavit]->TrackID();
6549 
6550  particlewithsedit++;
6551  }
6552  }
6553 
6554  //Sort particle ID's for each particle with sim energy deposit in this event by particle ID.
6555  std::sort(fData->ParticleIDSimEnergyDepositsTPCActivePerParticle.begin(), fData->ParticleIDSimEnergyDepositsTPCActivePerParticle.end());
6556 
6557 
6558  // Find number of sim energy deposits for each particle in this event and sort all SEDs by Particle ID.
6559  std::vector<int> it_sortedbyparticleID;
6560 
6561  int totalsed = 0;
6562  for(int psedavit = 0; psedavit < nParticlesWithSimEnergyDepositsTPCActive; psedavit++)
6563  {
6564  int NSEDForThisParticle = 0;
6565  for(int sedavit = 0; sedavit < nSimEnergyDepositsTPCActive; sedavit++)
6566  {
6567  if(energyDepositTPCActivelist[sedavit]->TrackID() == fData->ParticleIDSimEnergyDepositsTPCActivePerParticle[psedavit])
6568  {
6569  NSEDForThisParticle++;
6570  it_sortedbyparticleID.push_back(sedavit);
6571  }
6572  }
6573 
6574  fData->NSimEnergyDepositsTPCActivePerParticle[psedavit] = NSEDForThisParticle;
6575  totalsed += NSEDForThisParticle;
6576  }
6577 
6578 /*
6579  std::cout << std::endl;
6580  std::cout << "it_sortedbyparticleID.size(): " << it_sortedbyparticleID.size() << std::endl;
6581 
6582  for(int sedavit=0; sedavit < nSimEnergyDepositsTPCActive; sedavit++)
6583  {
6584  std::cout << std::endl;
6585  std::cout << "energyDepositTPCActivelist[" << sedavit << "]->TrackID(): " << energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->TrackID() << std::endl;
6586  std::cout << "energyDepositTPCActivelist[" << sedavit << "]->Time(): " << energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->Time() << std::endl;
6587  }
6588 */
6589 
6590 
6591 //Algorithm to sort SEDs by time
6592 /*
6593  //Now also sort SEDs by time
6594  //Sort by time (after sorting by particle ID)
6595  std::vector<int> it_sortedbyparticleIDandtime;
6596 
6597  int sedavit_currentparticle=0;
6598  int sedavit_mintime_currentparticle = -1;
6599 
6600 
6601  for(int psedavit = 0; psedavit < nParticlesWithSimEnergyDepositsTPCActive; psedavit++)
6602  {
6603  for(int NSEDForThisParticle = 0; NSEDForThisParticle < fData->NSimEnergyDepositsTPCActivePerParticle[psedavit]; NSEDForThisParticle++)
6604  {
6605  double mintime_currentparticle = 1e9;
6606 
6607  for(int sedavit = sedavit_currentparticle; sedavit < sedavit_currentparticle + fData->NSimEnergyDepositsTPCActivePerParticle[psedavit]; sedavit++)
6608  {
6609  if( energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->Time() < mintime_currentparticle && ( std::find(it_sortedbyparticleIDandtime.begin(), it_sortedbyparticleIDandtime.end(), sedavit) == it_sortedbyparticleIDandtime.end() ) )
6610  {
6611  mintime_currentparticle = energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->Time();
6612  sedavit_mintime_currentparticle = sedavit;
6613  }
6614  }
6615  it_sortedbyparticleIDandtime.push_back(sedavit_mintime_currentparticle);
6616  }
6617  sedavit_currentparticle+=fData->NSimEnergyDepositsTPCActivePerParticle[psedavit];
6618  }
6619 
6620 */
6621 
6622 
6623 //Alternative algorithm to sort SEDs by time
6624 /*
6625  //Sort by time (after sorting by particle ID)
6626  std::vector<int> it_sortedbyparticleIDandtime;
6627  it_sortedbyparticleIDandtime.resize(nSimEnergyDepositsTPCActive);
6628  FillWith(it_sortedbyparticleIDandtime, -1);
6629 
6630  int sedavit_sortedbyparticleIDandtime = 0;
6631  int mintime_sedavit = -1;
6632  int psedavit=0;
6633 
6634  //for(int sedavit_sortedbyparticleIDandtime = 0; sedavit_sortedbyparticleIDandtime < nSimEnergyDepositsTPCActive; i++)
6635  //{
6636  while(sedavit_sortedbyparticleIDandtime < nSimEnergyDepositsTPCActive )
6637  {
6638  double mintime = 1e9;
6639  bool FoundSEDForThisParticleID = false;
6640  int NSEDForThisParticle = 0;
6641 
6642  for(int sedavit = 0; sedavit < nSimEnergyDepositsTPCActive; sedavit++)
6643  {
6644  if( energyDepositTPCActivelist[sedavit]->TrackID() == fData->ParticleIDSimEnergyDepositsTPCActivePerParticle[psedavit] )
6645  {
6646  if( energyDepositTPCActivelist[sedavit]->Time() < mintime && ( std::find(it_sortedbyparticleIDandtime.begin(), it_sortedbyparticleIDandtime.end(), sedavit) == it_sortedbyparticleIDandtime.end() ) )
6647  {
6648  mintime = energyDepositTPCActivelist[sedavit]->Time();
6649  mintime_sedavit = sedavit;
6650  FoundSEDForThisParticleID = true;
6651  }
6652  }
6653  }
6654 
6655  if( FoundSEDForThisParticleID )
6656  {
6657  it_sortedbyparticleIDandtime[sedavit_sortedbyparticleIDandtime] = mintime_sedavit;
6658  sedavit_sortedbyparticleIDandtime++;
6659  }
6660  else
6661  {
6662  psedavit++;
6663  }
6664  }
6665 */
6666 
6667  // For each energy deposit in this event (sorted by particle ID, not by time)
6668 
6669  for(int sedavit = 0; sedavit < nSimEnergyDepositsTPCActive; sedavit++)
6670  {
6671  fData->SEDTPCAVTrackID[sedavit] = energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->TrackID();
6672  fData->SEDTPCAVPDGCode[sedavit] = energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->PdgCode();
6673  fData->SEDTPCAVEnergy[sedavit] = energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->Energy();
6674  fData->SEDTPCAVNumPhotons[sedavit] = energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->NumPhotons();
6675  fData->SEDTPCAVNumElectrons[sedavit] = energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->NumElectrons();
6676  fData->SEDTPCAVLength[sedavit] = energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->StepLength();
6677 
6678  fData->SEDTPCAVStartTime[sedavit] = energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->StartT();
6679  fData->SEDTPCAVStartX[sedavit] = energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->StartX();
6680  fData->SEDTPCAVStartY[sedavit] = energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->StartY();
6681  fData->SEDTPCAVStartZ[sedavit] = energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->StartZ();
6682 
6683  fData->SEDTPCAVMidTime[sedavit] = energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->Time();
6684  fData->SEDTPCAVMidX[sedavit] = energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->MidPointX();
6685  fData->SEDTPCAVMidY[sedavit] = energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->MidPointY();
6686  fData->SEDTPCAVMidZ[sedavit] = energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->MidPointZ();
6687 
6688  fData->SEDTPCAVEndTime[sedavit] = energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->EndT();
6689  fData->SEDTPCAVEndX[sedavit] = energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->EndX();
6690  fData->SEDTPCAVEndY[sedavit] = energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->EndY();
6691  fData->SEDTPCAVEndZ[sedavit] = energyDepositTPCActivelist[it_sortedbyparticleID[sedavit]]->EndZ();
6692 
6693 
6694  if(fLogLevel >= 5)
6695  {
6696  std::cout << std::endl;
6697  std::cout << "sedavit: " << sedavit << std::endl;
6698  std::cout << "fData->SEDTPCAVTrackID[" << sedavit << "]: " << fData->SEDTPCAVTrackID[sedavit] << std::endl;
6699  std::cout << "fData->SEDTPCAVPDGCode[" << sedavit << "]: " << fData->SEDTPCAVPDGCode[sedavit] << std::endl;
6700  std::cout << "fData->SEDTPCAVEnergy[" << sedavit << "]: " << fData->SEDTPCAVEnergy[sedavit] << std::endl;
6701  std::cout << "fData->SEDTPCAVNumPhotons[" << sedavit << "]: " << fData->SEDTPCAVNumPhotons[sedavit] << std::endl;
6702  std::cout << "fData->SEDTPCAVNumElectrons[" << sedavit << "]: " << fData->SEDTPCAVNumElectrons[sedavit] << std::endl;
6703 
6704  std::cout << "fData->SEDTPCAVLength[" << sedavit << "]: " << fData->SEDTPCAVLength[sedavit] << std::endl;
6705  std::cout << "fData->SEDTPCAVStartTime[" << sedavit << "]: " << fData->SEDTPCAVStartTime[sedavit] << std::endl;
6706  std::cout << "fData->SEDTPCAVStartX[" << sedavit << "]: " << fData->SEDTPCAVStartX[sedavit] << std::endl;
6707  std::cout << "fData->SEDTPCAVStartY[" << sedavit << "]: " << fData->SEDTPCAVStartY[sedavit] << std::endl;
6708  std::cout << "fData->SEDTPCAVStartZ[" << sedavit << "]: " << fData->SEDTPCAVStartZ[sedavit] << std::endl;
6709  std::cout << "fData->SEDTPCAVMidTime[" << sedavit << "]: " << fData->SEDTPCAVMidTime[sedavit] << std::endl;
6710  std::cout << "fData->SEDTPCAVMidX[" << sedavit << "]: " << fData->SEDTPCAVMidX[sedavit] << std::endl;
6711  std::cout << "fData->SEDTPCAVMidY[" << sedavit << "]: " << fData->SEDTPCAVMidY[sedavit] << std::endl;
6712  std::cout << "fData->SEDTPCAVMidZ[" << sedavit << "]: " << fData->SEDTPCAVMidZ[sedavit] << std::endl;
6713  std::cout << "fData->SEDTPCAVEndTime[" << sedavit << "]: " << fData->SEDTPCAVEndTime[sedavit] << std::endl;
6714  std::cout << "fData->SEDTPCAVEndX[" << sedavit << "]: " << fData->SEDTPCAVEndX[sedavit] << std::endl;
6715  std::cout << "fData->SEDTPCAVEndY[" << sedavit << "]: " << fData->SEDTPCAVEndY[sedavit] << std::endl;
6716  std::cout << "fData->SEDTPCAVEndZ[" << sedavit << "]: " << fData->SEDTPCAVEndZ[sedavit] << std::endl;
6717  }
6718  }
6719  }
6720  }//if (mcevts_truth)
6721  }//if (fIsMC){
6722 
6723  fData->taulife = detProp.ElectronLifetime();
6724 
6725  fTree->Fill();
6726 
6727  if (mf::isDebugEnabled()) {
6728  // use mf::LogDebug instead of MF_LOG_DEBUG because we reuse it in many lines;
6729  // thus, we protect this part of the code with the line above
6730  mf::LogDebug logStream("AnaRootParserStructure");
6731  logStream
6732  << "Tree data structure contains:"
6733  << "\n - " << fData->no_hits << " hits (" << fData->GetMaxHits() << ")"
6734  << "\n - " << fData->NHitsInAllTracks << " hits (" << fData->GetMaxHits() << ")"
6735  << "\n - " << fData->genie_no_primaries << " genie primaries (" << fData->GetMaxGeniePrimaries() << ")"
6736  << "\n - " << fData->geant_list_size << " GEANT particles (" << fData->GetMaxGEANTparticles() << "), "
6737  << fData->no_primaries << " primaries"
6738  << "\n - " << fData->geant_list_size_in_tpcAV << " GEANT particles in AV "
6739  << "\n - " << ((int) fData->kNTracker) << " trackers:"
6740  ;
6741 
6742  size_t iTracker = 0;
6743  for (auto tracker = fData->TrackData.cbegin();
6744  tracker != fData->TrackData.cend(); ++tracker, ++iTracker
6745  ) {
6746  logStream
6747  << "\n -> " << tracker->ntracks << " " << fTrackModuleLabel[iTracker]
6748  << " tracks (" << tracker->GetMaxTracks() << ")"
6749  ;
6750  for (int iTrk = 0; iTrk < tracker->ntracks; ++iTrk) {
6751  logStream << "\n [" << iTrk << "] "<< tracker->ntrkhitsperview[iTrk][0];
6752  for (size_t ipl = 1; ipl < tracker->GetMaxPlanesPerTrack(iTrk); ++ipl)
6753  logStream << " + " << tracker->ntrkhitsperview[iTrk][ipl];
6754  logStream << " hits (" << tracker->GetMaxHitsPerTrack(iTrk, 0);
6755  for (size_t ipl = 1; ipl < tracker->GetMaxPlanesPerTrack(iTrk); ++ipl)
6756  logStream << " + " << tracker->GetMaxHitsPerTrack(iTrk, ipl);
6757  logStream << ")";
6758  } // for tracks
6759  } // for trackers
6760  } // if logging enabled
6761 
6762  // if we don't use a permanent buffer (which can be huge),
6763  // delete the current buffer, and we'll create a new one on the next event
6764 
6765  if (!fUseBuffer) {
6766  MF_LOG_DEBUG("AnaRootParserStructure") << "Freeing the tree data structure";
6767  DestroyData();
6768  }
6769  } // dune::AnaRootParser::analyze()
6770 
6771 
6773  recob::Shower const& shower, const bool fSavePFParticleInfo,
6774  const std::map<Short_t, Short_t> &showerIDtoPFParticleIDMap
6775  ) const {
6776 
6777  showerData.showerID[iShower] = shower.ID();
6778  showerData.shwr_bestplane[iShower] = shower.best_plane();
6779  showerData.shwr_length[iShower] = shower.Length();
6780 
6781  TVector3 const& dir_start = shower.Direction();
6782  showerData.shwr_startdcosx[iShower] = dir_start.X();
6783  showerData.shwr_startdcosy[iShower] = dir_start.Y();
6784  showerData.shwr_startdcosz[iShower] = dir_start.Z();
6785 
6786  TVector3 const& pos_start = shower.ShowerStart();
6787  showerData.shwr_startx[iShower] = pos_start.X();
6788  showerData.shwr_starty[iShower] = pos_start.Y();
6789  showerData.shwr_startz[iShower] = pos_start.Z();
6790 
6791  if (fSavePFParticleInfo) {
6792  auto mapIter = showerIDtoPFParticleIDMap.find(shower.ID());
6793  if (mapIter != showerIDtoPFParticleIDMap.end()) {
6794  // This vertex has a corresponding PFParticle.
6795  showerData.shwr_hasPFParticle[iShower] = 1;
6796  showerData.shwr_PFParticleID[iShower] = mapIter->second;
6797  }
6798  else
6799  showerData.shwr_hasPFParticle[iShower] = 0;
6800  }
6801 
6802  if (shower.Energy().size() == kNplanes)
6803  std::copy_n
6804  (shower.Energy().begin(), kNplanes, &showerData.shwr_totEng[iShower][0]);
6805  if (shower.dEdx().size() == kNplanes)
6806  std::copy_n
6807  (shower.dEdx().begin(), kNplanes, &showerData.shwr_dedx[iShower][0]);
6808  if (shower.MIPEnergy().size() == kNplanes)
6809  std::copy_n
6810  (shower.MIPEnergy().begin(), kNplanes, &showerData.shwr_mipEng[iShower][0]);
6811 
6812  } // dune::AnaRootParser::FillShower()
6813 
6814 
6816  std::vector<recob::Shower> const& showers, const bool fSavePFParticleInfo,
6817  const std::map<Short_t, Short_t> &showerIDtoPFParticleIDMap
6818  ) const {
6819 
6820  const size_t NShowers = showers.size();
6821 
6822  //
6823  // prepare the data structures, the tree and the connection between them
6824  //
6825 
6826  // allocate enough space for this number of showers
6827  // (but at least for one of them!)
6828  showerData.SetMaxShowers(std::max(NShowers, (size_t) 1));
6829  showerData.Clear(); // clear all the data
6830 
6831  // now set the tree addresses to the newly allocated memory;
6832  // this creates the tree branches in case they are not there yet
6833  showerData.SetAddresses(fTree);
6834  if (NShowers > showerData.GetMaxShowers()) {
6835  // got this error? it might be a bug,
6836  // since we are supposed to have allocated enough space to fit all showers
6837  mf::LogError("AnaRootParser:limits") << "event has " << NShowers
6838  << " " << showerData.Name() << " showers, only "
6839  << showerData.GetMaxShowers() << " stored in tree";
6840  }
6841 
6842  //
6843  // now set the data
6844  //
6845  // set the record of the number of showers
6846  // (data structures are already properly resized)
6847  showerData.nshowers = (Short_t) NShowers;
6848 
6849  // set all the showers one by one
6850  for (size_t i = 0; i < NShowers; ++i) FillShower(showerData, i, showers[i], fSavePFParticleInfo, showerIDtoPFParticleIDMap);
6851 
6852  } // dune::AnaRootParser::FillShowers()
6853 
6854 
6855 
6856 void dune::AnaRootParser::HitsBackTrack(detinfo::DetectorClocksData const& clockData, art::Ptr<recob::Hit> const& hit, int & trackid, float & maxe, float & purity){
6857 
6858  trackid = -1;
6859  purity = -1;
6860 
6862 
6863  std::map<int,double> trkide;
6864  std::vector<sim::IDE> ides;
6865 
6866  //bt_serv->HitToSimIDEs(hit,ides);
6867  std::vector<sim::TrackIDE> eveIDs = bt_serv->HitToEveTrackIDEs(clockData, hit);
6868 
6869  for(size_t e = 0; e < eveIDs.size(); ++e){
6870  //std::cout<<" "<<e<<" "<<eveIDs[e].trackID<<" "<<eveIDs[e].energy<<" "<<eveIDs[e].energyFrac<<std::endl;
6871  trkide[eveIDs[e].trackID] += eveIDs[e].energy;
6872  }
6873 
6874  maxe = 0;
6875  double tote = 0;
6876  for (std::map<int,double>::iterator ii = trkide.begin(); ii!=trkide.end(); ++ii){
6877  tote += ii->second;
6878  if ((ii->second)>maxe){
6879  maxe = ii->second;
6880  trackid = ii->first;
6881  }
6882  }
6883 
6884  //std::cout << "the total energy of this reco track is: " << tote << std::endl;
6885  if (tote>0){
6886  purity = maxe/tote;
6887  }
6888  }
6889 
6890  // Calculate distance to boundary.
6891  double dune::AnaRootParser::bdist(const TVector3& pos)
6892  {
6893  double d1 = -ActiveBounds[0] + pos.X();
6894  double d2 = ActiveBounds[1] - pos.X();
6895  double d3 = -ActiveBounds[2] + pos.Y();
6896  double d4 = ActiveBounds[3] - pos.Y();
6897  double d5 = -ActiveBounds[4] + pos.Z();
6898  double d6 = ActiveBounds[5] - pos.Z();
6899 
6900  double Xmin = std::min(d1, d2);
6901  double result = 0;
6902  if (Xmin<0) result = std::min(std::min(std::min( d3, d4), d5), d6); // - FIXME Passing uncorrected hits means X positions are very wrong ( outside of ActiveVolume )
6903  else result = std::min(std::min(std::min(std::min(Xmin, d3), d4), d5), d6);
6904  if (result<-1) result = -1;
6905  /*
6906  std::cout << "\n" << std::endl;
6907  std::cout << "-"<<ActiveBounds[0]<<" + "<<pos.X()<< " = " << d1 << "\n"
6908  << ActiveBounds[1]<<" - "<<pos.X()<< " = " << d2 << "\n"
6909  << "-"<<ActiveBounds[2]<<" + "<<pos.Y()<< " = " << d3 << "\n"
6910  << ActiveBounds[3]<<" - "<<pos.Y()<< " = " << d4 << "\n"
6911  << "-"<<ActiveBounds[4]<<" + "<<pos.Z()<< " = " << d5 << "\n"
6912  << ActiveBounds[5]<<" - "<<pos.Z()<< " = " << d6 << "\n"
6913  << "And the Minimum is " << result << std::endl;
6914  */
6915  return result;
6916  }
6917 
6918  // Length of reconstructed track, trajectory by trajectory.
6920  {
6921  return track.Length();
6922  }
6923 
6924 
6926  const sim::MCTrack& mctrack, TLorentzVector& tpcstart, TLorentzVector& tpcend, TLorentzVector& tpcmom){
6927  auto const* geom = lar::providerFrom<geo::Geometry>();
6928 
6929  //compute the drift x range
6930  double vDrift = detProp.DriftVelocity()*1e-3; //cm/ns
6931  double xrange[2] = {DBL_MAX, -DBL_MAX };
6932  for (unsigned int c=0; c<geom->Ncryostats(); ++c) {
6933  for (unsigned int t=0; t<geom->NTPC(c); ++t) {
6934  double Xat0 = detProp.ConvertTicksToX(0,0,t,c);
6935  double XatT = detProp.ConvertTicksToX(detProp.NumberTimeSamples(),0,t,c);
6936  xrange[0] = std::min(std::min(Xat0, XatT), xrange[0]);
6937  xrange[1] = std::max(std::max(Xat0, XatT), xrange[1]);
6938  }
6939  }
6940 
6941  double result = 0.;
6942  TVector3 disp;
6943  bool first = true;
6944 
6945  for(auto step: mctrack) {
6946  // check if the particle is inside a TPC
6947  if (step.X() >= ActiveBounds[0] && step.X() <= ActiveBounds[1] &&
6948  step.Y() >= ActiveBounds[2] && step.Y() <= ActiveBounds[3] &&
6949  step.Z() >= ActiveBounds[4] && step.Z() <= ActiveBounds[5] ){
6950  // Doing some manual shifting to account for
6951  // an interaction not occuring with the beam dump
6952  // we will reconstruct an x distance different from
6953  // where the particle actually passed to to the time
6954  // being different from in-spill interactions
6955  double newX = step.X()+(step.T()*vDrift);
6956  if (newX < xrange[0] || newX > xrange[1]) continue;
6957 
6958  TLorentzVector pos(newX,step.Y(),step.Z(),step.T());
6959  if(first){
6960  tpcstart = pos;
6961  tpcmom = step.Momentum();
6962  first = false;
6963  }
6964  else {
6965  disp -= pos.Vect();
6966  result += disp.Mag();
6967  }
6968  disp = pos.Vect();
6969  tpcend = pos;
6970  }
6971  }
6972  return result;
6973  }
6974 
6975  // Length of MC particle, trajectory by trajectory (with the manual shifting for x correction)
6977  const simb::MCParticle& p, TLorentzVector& start, TLorentzVector& end, unsigned int &starti, unsigned int &endi)
6978  {
6979  auto const* geom = lar::providerFrom<geo::Geometry>();
6980 
6981  //compute the drift x range
6982  double vDrift = detProp.DriftVelocity()*1e-3; //cm/ns
6983  double xrange[2] = {DBL_MAX, -DBL_MAX };
6984  for (unsigned int c=0; c<geom->Ncryostats(); ++c) {
6985  for (unsigned int t=0; t<geom->NTPC(c); ++t) {
6986  double Xat0 = detProp.ConvertTicksToX(0,0,t,c);
6987  double XatT = detProp.ConvertTicksToX(detProp.NumberTimeSamples(),0,t,c);
6988  xrange[0] = std::min(std::min(Xat0, XatT), xrange[0]);
6989  xrange[1] = std::max(std::max(Xat0, XatT), xrange[1]);
6990  }
6991  }
6992 
6993  double result = 0.;
6994  TVector3 disp;
6995  bool first = true;
6996 
6997  for(unsigned int i = 0; i < p.NumberTrajectoryPoints(); ++i) {
6998  // check if the particle is inside a TPC
6999  if (p.Vx(i) >= ActiveBounds[0] && p.Vx(i) <= ActiveBounds[1] &&
7000  p.Vy(i) >= ActiveBounds[2] && p.Vy(i) <= ActiveBounds[3] &&
7001  p.Vz(i) >= ActiveBounds[4] && p.Vz(i) <= ActiveBounds[5]){
7002  // Doing some manual shifting to account for
7003  // an interaction not occuring with the beam dump
7004  // we will reconstruct an x distance different from
7005  // where the particle actually passed to to the time
7006  // being different from in-spill interactions
7007  double newX = p.Vx(i)+(p.T(i)*vDrift);
7008  if (newX < xrange[0] || newX > xrange[1]) continue;
7009  TLorentzVector pos(newX,p.Vy(i),p.Vz(i),p.T());
7010  if(first){
7011  start = pos;
7012  starti=i;
7013  first = false;
7014  }
7015  else {
7016  disp -= pos.Vect();
7017  result += disp.Mag();
7018  }
7019  disp = pos.Vect();
7020  end = pos;
7021  endi = i;
7022  }
7023  }
7024  return result;
7025  }
7026 
7027  // Length of MC particle, trajectory by trajectory (with out the manual shifting for x correction)
7028  double dune::AnaRootParser::length(const simb::MCParticle& p, TLorentzVector& start, TLorentzVector& end, unsigned int &starti, unsigned int &endi)
7029  {
7030  double result = 0.;
7031  TVector3 disp;
7032  bool first = true;
7033 
7034  for(unsigned int i = 0; i < p.NumberTrajectoryPoints(); ++i) {
7035  // check if the particle is inside a TPC
7036  if (p.Vx(i) >= ActiveBounds[0] && p.Vx(i) <= ActiveBounds[1] && p.Vy(i) >= ActiveBounds[2] && p.Vy(i) <= ActiveBounds[3] && p.Vz(i) >= ActiveBounds[4] && p.Vz(i) <= ActiveBounds[5]){
7037  if(first){
7038  start = p.Position(i);
7039  first = false;
7040  starti = i;
7041  }else{
7042  disp -= p.Position(i).Vect();
7043  result += disp.Mag();
7044  }
7045  disp = p.Position(i).Vect();
7046  end = p.Position(i);
7047  endi = i;
7048  }
7049  }
7050  return result;
7051  }
7052 
7053  //......................................................................
7055  const art::InputTag& which,
7056  unsigned int cryostat,
7057  unsigned int tpc,
7058  unsigned int plane)
7059  {
7060  std::vector<const recob::Hit*> temp;
7061  int NumberOfHitsBeforeThisPlane=0;
7062  evt.getView(which, temp); //temp.size() = total number of hits for this event (number of all hits in all Cryostats, TPC's, planes and wires)
7063  for(size_t t = 0; t < temp.size(); ++t){
7064  if( temp[t]->WireID().Cryostat == cryostat&& temp[t]->WireID().TPC == tpc && temp[t]->WireID().Plane == plane ) break;
7065  NumberOfHitsBeforeThisPlane++;
7066  }
7067  return NumberOfHitsBeforeThisPlane;
7068  }
7069 
7070  namespace dune{
7071 
7073 
7074  }
std::vector< std::string > mctrk_Process
def analyze(root, level, gtrees, gbranches, doprint)
Definition: rootstat.py:69
static QCString name
Definition: declinfo.cpp:673
double E(const int i=0) const
Definition: MCParticle.h:233
Int_t geant_trajectory_size
! how many trajectory points for all geant particles there is currently room for
std::vector< Float_t > mcshwr_CombEngE
int best_plane() const
Definition: Shower.h:200
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
void XYZ(double *xyz) const
Legacy method to access vertex position, preserved to avoid breaking code. Please try to use Vertex::...
Definition: Vertex.cxx:36
void ResizeGEANTInAV(int nParticlesInAV)
Resize the data strutcure for GEANT particles in active volume.
std::vector< Float_t > EndPx_tpcAV
intermediate_table::iterator iterator
AuxDetMCData_t< Float_t > exitPx
Exit x momentum of particle out of AuxDet.
std::vector< Float_t > mcshwr_endZ
std::vector< Float_t > EndPointz_drifted
unsigned int NumberTrajectoryPoints() const
Definition: MCParticle.h:218
PFParticleData_t< Short_t > pfp_isShower
whether this PFParticle corresponds to a shower
const TVector3 & ShowerStart() const
Definition: Shower.h:192
const TLorentzVector & Position(const int i=0) const
Definition: MCParticle.h:219
std::vector< Float_t > StartT_drifted
simb::Origin_t Origin() const
Definition: MCTrack.h:40
ShowerPlaneData_t< Float_t > shwr_mipEng
Total MIP energy of the shower per plane.
int PdgCode() const
Definition: MCParticle.h:212
std::vector< Float_t > cry_StartPointz
std::vector< std::string > fCalorimetryModuleLabel
constexpr std::uint32_t timeLow() const
Definition: Timestamp.h:29
ShowerPlaneData_t< Float_t > shwr_dedx
dE/dx of the shower per plane
std::vector< Float_t > StartPointz_tpcAV
bool fSaveHitInfo
whether to extract and save MC Track information
void DestroyData()
Destroy the local buffers (existing branches will point to invalid address!)
double VertexMomentum() const
Definition: Track.h:142
std::vector< Float_t > EndPointy_drifted
std::vector< Int_t > mcshwr_isEngDeposited
Little helper functor class to create or reset branches in a tree.
std::vector< Float_t > mcshwr_CombEngX
const MCStep & End() const
Definition: MCShower.h:56
Creates a simple ROOT tree with tracking and calorimetry information.
std::vector< Float_t > mcshwr_startY
double Py(const int i=0) const
Definition: MCParticle.h:231
TrackDataStruct()
Creates an empty tracker data structure.
float SummedADCaverage() const
Returns the average signal ADC counts of the cluster hits.
Definition: Cluster.h:656
int ntracks
Definition: tracks.py:246
float IntegralAverage() const
Returns the average charge of the cluster hits.
Definition: Cluster.h:622
size_t GetMaxParticlesWithSimEnergyDepositsTPCActive() const
Returns the number of particles with SimEnergyDepositsTPCActive for which memory is allocated...
constexpr int kMaxClusters
PFParticleData_t< Short_t > pfp_selfID
the PFParticles&#39; own IDs
void SetAddresses()
Sets the addresses of all the tree branches, creating the missing ones.
std::vector< std::string > fMCT0FinderLabel
std::vector< Float_t > thetastart_tpcAV
static constexpr size_t size()
begin/end interface
float bwdLogLikelihood() const
minimum negative log likelihood value from fit assuming a backward track direction ...
Definition: MCSFitResult.h:44
double EndE() const
Definition: MCParticle.h:244
static QCString result
const TLorentzVector & EndPosition() const
Definition: MCParticle.h:225
size_t GetMaxGEANTtrajectorypoints() const
Returns the number of GEANT trajectory steps for which memory is allocated.
ShowerData_t< Short_t > shwr_bestplane
Shower best plane.
bool hasGeantInAVInfo() const
Returns whether we have Geant data.
PFParticleData_t< Short_t > pfp_vertexID
the ID of the vertex belonging to this PFParticle
bool fSaveGeantTrajectoryInfo
whether to extract and save Geant information
void endSubRun(const art::SubRun &sr)
std::vector< Float_t > StartPx_tpcAV
Int_t generator_list_size
! how many particles there is currently room for
Short_t nPFParticles
the total number of PFParticles
bool fSaveGeantInfo
whether to extract and save Geant information
ShowerDataStruct(std::string new_name="", size_t maxShowers=0)
Creates a shower data structure allowing up to maxShowers showers.
bool fSaveSimEnergyDepositTPCActiveInfo
whether to extract and save Geant information
std::vector< Float_t > mcshwr_AncestorendZ
std::map< art::Ptr< recob::PFParticle >, ClusterVector > PFParticlesToClusters
double Length() const
Definition: Shower.h:201
AuxDetMCData_t< Float_t > exitT
Exit T position of particle out of AuxDet.
std::vector< Float_t > mcshwr_MotherendY
AdcChannelData::View View
AnaRootParserDataStruct(size_t nTrackers=0, size_t nVertexAlgos=0, std::vector< std::string > const &ShowerAlgos={})
Constructor; clears all fields.
unsigned int TrackID() const
Definition: MCShower.h:53
static bool IsNeutrino(const art::Ptr< recob::PFParticle > particle)
Determine whether a particle has been reconstructed as a neutrino.
constexpr int kMaxNPFPNeutrinos
void HitsBackTrack(detinfo::DetectorClocksData const &clockData, art::Ptr< recob::Hit > const &hit, int &trackid, float &maxe, float &purity)
Handle< PROD > getHandle(SelectorBase const &) const
Definition: DataViewImpl.h:382
std::vector< Float_t > mctrk_AncestorendZ
std::string string
Definition: nybbler.cc:12
unsigned int ID
std::vector< Float_t > StartP_tpcAV
bool fIsMC
whether to use a permanent buffer (faster, huge memory)
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
constexpr int kMaxVertices
const std::string & AncestorProcess() const
Definition: MCTrack.h:57
float bwdMomentum() const
momentum value from fit assuming a backward track direction
Definition: MCSFitResult.h:38
std::vector< Float_t > StartE_drifted
int Mother() const
Definition: MCParticle.h:213
TrackDataStruct & GetTrackerData(size_t iTracker)
size_t GetNVertexAlgos() const
std::vector< BoxedArray< T[kMaxNDaughtersPerPFP]>> DaughterData_t
double ActiveBounds[6]
objet holding the configuration of the uBoone MCS fitting alg
Int_t simenergydeposit_size
! how many particles with sim energy deposits in TPC AV there is currently room for ...
size_t MaxVertices
maximum number of storable vertices
std::string fSimEnergyDepositTPCActiveLabel
constexpr std::uint32_t timeHigh() const
Definition: Timestamp.h:34
simb::Origin_t Origin() const
Definition: MCTruth.h:74
double Mass() const
Definition: MCParticle.h:239
constexpr T pow(T x)
Definition: pow.h:72
unsigned int bits
complementary information
constexpr int kMaxHits
Geometry information for a single TPC.
Definition: TPCGeo.h:38
const std::vector< double > & Energy() const
Definition: Shower.h:195
std::vector< Float_t > mcshwr_CombEngZ
bool fSaveGenieInfo
whether to extract and save CRY particle data
std::vector< Float_t > mcshwr_CombEngY
double Px(const int i=0) const
Definition: MCParticle.h:230
std::vector< Float_t > StartPy_drifted
ShowerData_t< Float_t > shwr_startx
startx of shower
std::vector< std::string > mcshwr_AncestorProcess
ChannelGroupService::Name Name
const MCStep & MotherEnd() const
Definition: MCTrack.h:53
unsigned int AncestorTrackID() const
Definition: MCTrack.h:56
std::vector< Float_t > mcshwr_CombEngPy
static std::unique_ptr< FVectorReader > create(const art::Event &evt, const art::InputTag &tag)
Definition: MVAReader.h:29
size_t GetNTrackers() const
Returns the number of trackers configured.
void CheckTree(std::string caller) const
Helper function: throws if no tree is available.
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
Definition: Track.h:102
Class to keep data related to recob::Hit associated with recob::Track.
ShowerPlaneData_t< Float_t > shwr_totEng
Total energy of the shower per plane.
float StartWire() const
Returns the wire coordinate of the start of the cluster.
Definition: Cluster.h:286
int PdgCode() const
Definition: MCShower.h:52
Vector_t VertexDirection() const
Definition: Track.h:132
std::vector< Float_t > StartPointz_drifted
std::vector< std::string > mctrk_AncestorProcess
constexpr int kMaxShowerHits
static bool IsShower(const art::Ptr< recob::PFParticle > particle)
Determine whether a particle has been reconstructed as shower-like.
std::vector< Float_t > pathlen_drifted
std::vector< Float_t > mctrk_MotherendX
std::vector< Float_t > mcshwr_CombEngPx
std::vector< Float_t > EndP_drifted
std::vector< Int_t > NTrajectoryPointsPerParticle
double Mass(Resonance_t res)
resonance mass (GeV)
STL namespace.
std::vector< float > SEDTPCAVStartTime
const range_list_t & get_ranges() const
Returns the internal list of non-void ranges.
std::vector< Float_t > mctrk_MotherstartY
std::vector< Float_t > mctrk_len_drifted
int StatusCode() const
Definition: MCParticle.h:211
std::pair< float, std::string > P
void ResizePhotons(int nPhotons)
Resize the data strutcure for Generator particles.
int PdgCode() const
Return the type of particle as a PDG ID.
Definition: PFParticle.h:83
bool isCosmics
if it contains cosmics
Set of hits with a 2D structure.
Definition: Cluster.h:71
std::vector< art::Ptr< recob::Shower > > ShowerVector
intermediate_table::const_iterator const_iterator
float fG4minE
Energy threshold to save g4 particle info.
std::vector< Float_t > proto_momentum
float EndTick() const
Returns the tick coordinate of the end of the cluster.
Definition: Cluster.h:342
std::vector< Float_t > mcshwr_dEdx
void MarkMissing(TTree *pTree)
Applies a special prescription to mark shower information as missing.
AuxDetMCData_t< Float_t > entryZ
Entry Z position of particle into AuxDet.
std::string fPandoraNuVertexModuleLabel
int NParticles() const
Definition: MCTruth.h:75
size_t GetMaxTrackers() const
Returns the number of trackers for which memory is allocated.
float MultipleHitDensity() const
Density of wires in the cluster with more than one hit.
Definition: Cluster.h:723
std::vector< Float_t > cry_StartPointx
string dir
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
Cluster finding and building.
std::vector< Float_t > mcshwr_AncestorstartY
bool hasFlashInfo() const
Returns whether we have Flash data.
void FillShower(AnaRootParserDataStruct::ShowerDataStruct &showerData, size_t iShower, recob::Shower const &showers, const bool fSavePFParticleInfo, const std::map< Short_t, Short_t > &showerIDtoPFParticleIDMap) const
Stores the information of shower in slot iShower of showerData.
std::string Process() const
Definition: MCParticle.h:215
std::vector< std::string > fMVAPIDTrackModuleLabel
ShowerDataStruct & GetShowerData(size_t iShower)
bool fSaveGeantInAVInfo
whether to extract and save Geant information
int AncestorPdgCode() const
Definition: MCTrack.h:55
std::vector< Float_t > mctrk_AncestorendX
void SetTrackers(size_t nTrackers)
Allocates data structures for the given number of trackers (no Clear())
std::vector< Int_t > proto_isGoodParticle
std::string fExternalCounterModuleLabel
bool isValid() const
Returns if the cluster is valid (that is, if its ID is not invalid)
Definition: Cluster.h:753
const MCStep & End() const
Definition: MCTrack.h:45
float StartAngle() const
Returns the starting angle of the cluster.
Definition: Cluster.h:475
bool fUseBuffer
whether to use a permanent buffer (faster, huge memory)
void SetBits(unsigned int setbits, bool unset=false)
Sets the specified bits.
AuxDetMCData_t< Float_t > exitX
Exit X position of particle out of AuxDet.
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
void CreateTree(bool bClearData=false)
Create the output tree and the data structures, if needed.
std::map< art::Ptr< recob::PFParticle >, TrackVector > PFParticlesToTracks
std::vector< std::string > GetShowerAlgos() const
Returns the name of configured shower algorithms (converted to string)
std::vector< Float_t > mctrk_startZ
int NumberDaughters() const
Definition: MCParticle.h:217
std::vector< Float_t > EndPz_drifted
Class def header for mcstep data container.
bool hasGeneratorInfo() const
Returns whether we have Generator data.
unsigned int MotherTrackID() const
Definition: MCTrack.h:50
ClusterData_t< Short_t > pfp_clusterIDs
the IDs of any associated clusters
Int_t no_primaries
! how many particles there is currently room for
bool hasMCTrackInfo() const
Returns whether we have MCTrack data.
std::vector< Float_t > mcshwr_StartDirY
object containing MC flux information
art framework interface to geometry description
std::map< art::Ptr< recob::PFParticle >, VertexVector > PFParticlesToVertices
bool hasVertexInfo() const
Returns whether we have Vertex data.
size_t GetMaxPhotons() const
Returns the number of GEANT particles for which memory is allocated.
int TrackId() const
Definition: MCParticle.h:210
std::vector< Float_t > mcshwr_AncestorendX
recob::MCSFitResult fitMcs(const recob::TrackTrajectory &traj) const
AuxDetMCData_t< Float_t > exitPy
Exit y momentum of particle out of AuxDet.
total_extent<T>::value has the total number of elements of an array
std::vector< Float_t > photons_time
PFParticleData_t< Short_t > pfp_isTrack
whether this PFParticle corresponds to a track
bool fSaveGeneratorInfo
whether to extract and save collected photons
std::vector< BoxedArray< T[kNplanes][kMaxShowerHits]>> ShowerHitData_t
std::vector< Float_t > mctrk_startX
std::vector< std::string > mcshwr_Process
QuadExpr operator-(double v, const QuadExpr &e)
Definition: QuadExpr.h:38
static constexpr value_type value
bool isValid() const noexcept
Definition: Handle.h:191
std::vector< Float_t > mcshwr_CombEngPz
std::vector< BoxedArray< T[kMaxNClustersPerPFP]>> ClusterData_t
std::vector< Float_t > mcshwr_MotherendX
std::vector< Float_t > mctrk_MotherstartZ
int CountHits(const art::Event &evt, const art::InputTag &which, unsigned int cryostat, unsigned int tpc, unsigned int plane)
std::vector< Float_t > mcshwr_AncestorstartX
ShowerData_t< Float_t > shwr_startdcosz
Z directional cosine at start of shower.
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
const TVector3 & StartDir() const
Definition: MCShower.h:82
Collection of particles crossing one auxiliary detector cell.
bool hasProtoInfo() const
Returns whether we have protoDUNE beam primaries.
std::vector< std::string > fShowerModuleLabel
AuxDetMCData_t< Float_t > entryX
Entry X position of particle into AuxDet.
bool fSavePFParticleInfo
whether to extract and save Shower information
void ResizeSimEnergyDepositsTPCActive(int nSimEnergyDepositsTPCActive, int nParticlesWithSimEnergyDepositsTPCActive)
Resize the data strutcure for SimEnergyDepositTPCActive info.
bool hasHitInfo() const
Returns whether we have Hit data.
std::vector< VertexDataStruct > VertexData
T abs(T value)
float EndCharge() const
Returns the charge on the last wire of the cluster.
Definition: Cluster.h:498
Simulation objects for optical detectors.
double dEdx(float dqdx, float Efield)
Definition: doAna.cpp:21
float SummedADC() const
Returns the total charge of the cluster from signal ADC counts.
Definition: Cluster.h:634
double bdist(const TVector3 &pos)
bool hasCryInfo() const
Returns whether we have Cry data.
float bestMomentum() const
momentum for best direction fit
Definition: MCSFitResult.h:56
std::vector< Float_t > EndPointx_drifted
bool hasRecobWireInfo() const
Returns whether we have RecobWire data.
simb::Origin_t Origin() const
Definition: MCShower.h:50
std::vector< BoxedArray< T[kNplanes][kMaxTrackHits][3]>> TrackHitCoordData_t
Short_t pfp_numNeutrinos
the number of reconstructed neutrinos
const double e
size_t GetMaxGEANTparticles() const
Returns the number of GEANT particles for which memory is allocated.
double Length(size_t p=0) const
Access to various track properties.
Definition: Track.h:167
std::vector< std::string > fCosmicTaggerAssocLabel
whether to extract and save PFParticle information
std::map< art::Ptr< recob::PFParticle >, ShowerVector > PFParticlesToShowers
constexpr int kMaxTrackers
A wrapper to a C array (needed to embed an array into a vector)
std::vector< Float_t > mctrk_px_drifted
double Px() const
Definition: MCStep.h:46
DaughterData_t< Short_t > pfp_daughterIDs
the IDs of the daughter PFParticles
PFParticleDataStruct & GetPFParticleData()
Timestamp time() const
const std::vector< double > & dEdx() const
Definition: Shower.h:203
bool fSaveExternCounterInfo
whether to extract and save Flash information
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
std::vector< Float_t > mcshwr_MotherstartY
void ResizeGenerator(int nParticles)
Resize the data strutcure for Generator particles.
const std::vector< double > & MIPEnergy() const
Definition: Shower.h:198
int MotherPdgCode() const
Definition: MCShower.h:58
std::vector< Float_t > mcshwr_StartDirZ
const std::string & AncestorProcess() const
Definition: MCShower.h:66
std::vector< Int_t > mcshwr_MotherTrkId
std::vector< Float_t > mctrk_endX_drifted
TrackDataStruct(size_t maxTracks)
Creates a tracker data structure allowing up to maxTracks tracks.
SubRunData_t SubRunData
subrun data collected at begin of subrun
std::vector< Float_t > StartPz_drifted
constexpr int kMaxVertexAlgos
std::vector< art::Ptr< recob::PFParticle > > PFParticleVector
void ResizeGenie(int nPrimaries)
Resize the data strutcure for Genie primaries.
std::void_t< T > n
void SetVertexAlgos(size_t nVertexAlgos)
Allocates data structures for the given number of vertex algos (no Clear())
static void CollectShowers(const art::Event &evt, const std::string &label, ShowerVector &showerVector, PFParticlesToShowers &particlesToShowers)
Collect the reconstructed PFParticles and associated Showers from the ART event record.
trkf::TrajectoryMCSFitter fMCSFitter
std::vector< Handle< PROD > > getMany(SelectorBase const &selector=MatchAllSelector{}) const
Definition: DataViewImpl.h:479
float Chi2PerNdof() const
Definition: Track.h:169
PFParticleData_t< Short_t > pfp_isPrimary
whether the PFParticle is a primary particle
void SetAddresses(TTree *pTree, std::string tracker, bool isCosmics)
size_t GetNShowerAlgos() const
Returns the number of trackers for which data structures are allocated.
double P(const int i=0) const
Definition: MCParticle.h:234
key_type key() const noexcept
Definition: Ptr.h:216
T get(std::string const &key) const
Definition: ParameterSet.h:271
std::vector< Float_t > StartP_drifted
void CreateData(bool bClearData=false)
Creates the structure for the tree data; optionally initializes it.
std::vector< Float_t > StartPointx_drifted
bool fSavePhotonInfo
whether to extract and save ProtDUNE beam simulation information
float Width() const
A measure of the cluster width, in homogenized units.
Definition: Cluster.h:727
constexpr int kMaxFlashes
std::vector< std::string > fFlashT0FinderLabel
Point_t const & Vertex() const
Definition: Track.h:124
std::vector< std::string > fContainmentTaggerAssocLabel
size_t GetMaxGeneratorparticles() const
Returns the number of GEANT particles for which memory is allocated.
static void CollectVertices(const art::Event &evt, const std::string &label, VertexVector &vertexVector, PFParticlesToVertices &particlesToVertices)
Collect the reconstructed PFParticles and associated Vertices from the ART event record.
std::vector< Float_t > StartPx_drifted
std::vector< Int_t > mcshwr_AncestorTrkId
void SetVertexAddresses(size_t iVertexAlg)
double T(const int i=0) const
Definition: MCParticle.h:224
double length(const recob::Track &track)
std::vector< ShowerDataStruct > ShowerData
bool hasShowerInfo() const
Returns whether we have Shower data.
std::vector< Float_t > mctrk_endY_drifted
double Z() const
Definition: MCStep.h:44
bool fSaveShowerInfo
whether to extract and save External Counter information
size_t GetNTrackers() const
Returns the number of trackers for which data structures are allocated.
p
Definition: test.py:223
std::vector< Float_t > mctrk_AncestorstartX
constexpr int kMaxTruth
bool hasGeantTrajectoryInfo() const
Returns whether we have Geant trajectory data.
std::vector< Int_t > genie_status_code
VertexDataStruct & GetVertexData(size_t iVertex)
size_t NPoints() const
Definition: Track.h:103
bool hasClusterInfo() const
Returns whether we have Cluster data.
std::unique_ptr< AnaRootParserDataStruct > fData
AuxDetMCData_t< Float_t > exitY
Exit Y position of particle out of AuxDet.
SubRunNumber_t subRun() const
Definition: DataViewImpl.cc:78
PFParticleData_t< Short_t > pfp_numClusters
the number of associated clusters
bool fSaveProtoInfo
whether to extract and save Genie information
std::vector< BoxedArray< T[kMaxAuxDets]>> AuxDetMCData_t
std::vector< Float_t > StartPointy_drifted
bool IsPrimary() const
Returns whether the particle is the root of the flow.
Definition: PFParticle.h:86
bool isDebugEnabled()
size_t GetNShowerAlgos() const
Returns the number of shower algorithms configured.
std::vector< Float_t > proto_energy
const TVector3 & Direction() const
Definition: Shower.h:189
CodeOutputInterface * code
double Py() const
Definition: MCStep.h:47
std::vector< Float_t > mctrk_startZ_drifted
std::vector< Float_t > mctrk_AncestorstartY
std::vector< Float_t > StartPointx
bool fSaveCaloCosmics
save calorimetry information for cosmics
ShowerData_t< Float_t > shwr_length
Shower length.
double Y() const
Definition: MCStep.h:43
std::vector< art::Ptr< recob::Track > > TrackVector
const MCStep & AncestorStart() const
Definition: MCShower.h:67
RunNumber_t run() const
Definition: DataViewImpl.cc:71
static int max(int a, int b)
double EndT() const
Definition: MCParticle.h:229
double DriftVelocity(double efield=0., double temperature=0.) const
cm/us
constexpr unsigned short kMaxAuxDets
max number of auxiliary detector cells per MC particle
void SetShowerAlgos(std::vector< std::string > const &ShowerAlgos)
Allocates data structures for the given number of trackers (no Clear())
void FillShowers(AnaRootParserDataStruct::ShowerDataStruct &showerData, std::vector< recob::Shower > const &showers, const bool fSavePFParticleInfo, const std::map< Short_t, Short_t > &showerIDtoPFParticleIDMap) const
Stores the information of all showers into showerData.
ShowerData_t< Float_t > shwr_starty
starty of shower
const VertexDataStruct & GetVertexData(size_t iVertex) const
std::vector< Float_t > EndPointy_tpcAV
Class def header for mctrack data container.
std::vector< Float_t > EndPointx_tpcAV
const MCStep & AncestorStart() const
Definition: MCTrack.h:58
std::vector< std::string > fParticleIDModuleLabel
static void CollectTracks(const art::Event &evt, const std::string &label, TrackVector &trackVector, PFParticlesToTracks &particlesToTracks)
Collect the reconstructed PFParticles and associated Tracks from the ART event record.
std::vector< Float_t > StartPy_tpcAV
const std::string & MotherProcess() const
Definition: MCShower.h:60
std::vector< Float_t > EndPointz_tpcAV
Definition of data types for geometry description.
double driftedLength(detinfo::DetectorPropertiesData const &detProp, const simb::MCParticle &part, TLorentzVector &start, TLorentzVector &end, unsigned int &starti, unsigned int &endi)
static void CollectPFParticles(const art::Event &evt, const std::string &label, PFParticleVector &particleVector)
Collect the reconstructed PFParticles from the ART event record.
double dEdx() const
Definition: MCShower.h:81
std::vector< BoxedArray< T[kNplanes][kMaxTrackHits]>> TrackHitData_t
size_t GetMaxGeniePrimaries() const
Returns the number of GENIE primaries for which memory is allocated.
std::vector< Float_t > mcshwr_MotherendZ
std::vector< BoxedArray< T[kNplanes][kMaxShowerHits][3]>> ShowerHitCoordData_t
unsigned int AncestorTrackID() const
Definition: MCShower.h:65
bool fSaveRecobWireInfo
whether to extract and save raw digit information
int Ndof() const
Definition: Track.h:170
size_t GetMaxHits() const
Returns the number of hits for which memory is allocated.
bool bIgnoreMissingShowers
whether to ignore missing shower information
std::vector< Float_t > mctrk_py_drifted
const MCStep & AncestorEnd() const
Definition: MCShower.h:68
int PdgCode() const
Definition: MCTrack.h:41
const MCStep & DetProfile() const
Definition: MCShower.h:70
Detector simulation of raw signals on wires.
std::vector< std::string > fVertexModuleLabel
std::vector< Float_t > StartPointz
std::vector< Float_t > mctrk_pz_drifted
const sim::ParticleList & ParticleList() const
std::string name
name of the shower algorithm (for branch names)
Class storing the result of the Maximum Likelihood fit of Multiple Coulomb Scattering angles between ...
Definition: MCSFitResult.h:19
bool fSavePandoraNuVertexInfo
whether to extract and save Cluster information
double ConvertTicksToX(double ticks, int p, int t, int c) const
std::remove_all_extents< Array_t >::type Data_t
bool hasGenieInfo() const
Returns whether we have Genie data.
static void SelectNeutrinoPFParticles(const PFParticleVector &inputParticles, PFParticleVector &outputParticles)
Select reconstructed neutrino particles from a list of all reconstructed particles.
size_t GetMaxVertexAlgos() const
Returns the number of trackers for which memory is allocated.
bool fSaveRawDigitInfo
whether to extract and save Hit information
size_t GetMaxShowers() const
Returns the number of trackers for which memory is allocated.
bool fSaveMCShowerInfo
whether to extract and save Cluster information
bool fSaveClusterInfo
whether to extract and save Vertex information
const MCStep & Start() const
Definition: MCShower.h:55
ShowerData_t< Float_t > shwr_startdcosy
Y directional cosine at start of shower.
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
std::vector< Float_t > pathlen_tpcAV
void ResizeGEANTTrajectory(int nTrajectoryPoints)
Resize the data strutcure for GEANT trajectory info.
std::vector< Float_t > mcshwr_startZ
size_t GetNVertexAlgos() const
Returns the number of Vertex algos for which data structures are allocated.
bool hasGeantInfo() const
Returns whether we have Geant data.
ShowerData_t< Float_t > shwr_startz
startz of shower
bool hasRawDigitInfo() const
Returns whether we have RawDigit data.
double Vx(const int i=0) const
Definition: MCParticle.h:221
Class whose "type" contains the base data type of the container.
std::vector< Int_t > cry_primaries_pdg
std::vector< BoxedArray< T[kNplanes]>> ShowerPlaneData_t
int ID() const
Definition: Track.h:198
geo::View_t View() const
Returns the view for this cluster.
Definition: Cluster.h:741
constexpr int kMaxExternCounts
auto array(Array const &a)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:228
Declaration of signal hit object.
const MCStep & MotherStart() const
Definition: MCTrack.h:52
PFParticleData_t< Short_t > pfp_numDaughters
the number of daughters belonging to this PFParticle
std::vector< Float_t > photons_channel
std::vector< Float_t > phiend_tpcAV
size_t MaxShowers
maximum number of storable showers
std::vector< Int_t > mcshwr_Ancestorpdg
PFParticleData_t< Short_t > pfp_isNeutrino
whether this PFParticle is a neutrino
bool hasTrackInfo() const
Returns whether we have Track data.
void SetTrackerAddresses(size_t iTracker)
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
DoubleProduct operator+(DoubleProduct const &left, DoubleProduct const right)
Definition: ToyProducts.h:97
int MotherPdgCode() const
Definition: MCTrack.h:49
const MCStep & MotherEnd() const
Definition: MCShower.h:62
def fill(s)
Definition: translator.py:93
PFParticleData_t< Short_t > pfp_trackID
the ID of the track object corresponding to this PFParticle, if !isShower
std::vector< Float_t > mcshwr_MotherstartZ
std::vector< Float_t > EndPy_drifted
std::vector< Float_t > StartPointx_tpcAV
std::vector< Float_t > mcshwr_AncestorendY
std::vector< Float_t > mctrk_MotherendY
Contains all timing reference information for the detector.
float StartCharge() const
Returns the charge on the first wire of the cluster.
Definition: Cluster.h:454
void ResizeProto(int nPrimaries)
Resize the data structure for ProtoDUNE primaries.
std::vector< Float_t > EndPy_tpcAV
std::vector< Float_t > EndT_drifted
bool fSaveFlashInfo
whether to extract and save nu vertex information from Pandora
std::vector< Float_t > mctrk_AncestorstartZ
ID_t ID() const
Identifier of this cluster.
Definition: Cluster.h:738
std::vector< Float_t > mctrk_startY_drifted
AuxDetMCData_t< Float_t > exitPz
Exit z momentum of particle out of AuxDet.
bool fSaveAuxDetInfo
whether to extract and save auxiliary detector data
std::vector< Float_t > mctrk_startY
bool hasExternCountInfo() const
Returns whether we have External Counter data.
std::vector< std::string > fMVAPIDShowerModuleLabel
std::vector< Float_t > mcshwr_startX
bool fSaveTrackInfo
whether to extract and save recob wire information
PFParticleDataStruct(size_t maxPFParticles=0)
Creates a PFParticle data structure allowing up to maxPFParticles PFParticles.
Vector_t EndDirection() const
Definition: Track.h:133
std::vector< Float_t > mctrk_p_drifted
std::vector< Float_t > StartT_tpcAV
AuxDetMCData_t< Short_t > AuxDetID
Which AuxDet this particle went through.
contains information for a single step in the detector simulation
MC truth information to make RawDigits and do back tracking.
std::vector< Int_t > mctrk_AncestorTrkId
void ResizeGEANT(int nParticles)
Resize the data strutcure for GEANT particles.
std::vector< Float_t > mctrk_MotherendZ
PFParticleData_t< Short_t > pfp_parentID
the ID of this PFParticle&#39;s immediate parent
void SetAddresses(TTree *pTree, std::vector< std::string > const &trackers, std::vector< std::string > const &vertexalgos, std::vector< std::string > const &showeralgos, bool isCosmics)
Connect this object with a tree.
std::vector< sim::TrackIDE > HitToEveTrackIDEs(detinfo::DetectorClocksData const &clockData, recob::Hit const &hit) const
std::vector< TrackDataStruct > TrackData
std::vector< Float_t > mctrk_endZ_drifted
const TLorentzVector & Momentum(const int i=0) const
Definition: MCParticle.h:220
const PFParticleDataStruct & GetPFParticleData() const
const std::string & Process() const
Definition: MCTrack.h:43
def center(depos, point)
Definition: depos.py:117
const std::string & MotherProcess() const
Definition: MCTrack.h:51
std::vector< std::string > fFlashMatchAssocLabel
std::vector< Float_t > mctrk_startX_drifted
bool hasSimEnergyDepositTPCActiveInfo() const
Returns whether we have Geant trajectory data.
static QCString type
Definition: declinfo.cpp:672
#define MF_LOG_DEBUG(id)
static bool IsTrack(const art::Ptr< recob::PFParticle > particle)
Determine whether a particle has been reconstructed as track-like.
bool hasAuxDetector() const
Returns whether we have auxiliary detector data.
std::vector< Int_t > NSimEnergyDepositsTPCActivePerParticle
double Pz(const int i=0) const
Definition: MCParticle.h:232
Provides recob::Track data product.
bool hasPandoraNuVertexInfo() const
Returns whether we have Pandora Nu Vertex data.
std::vector< Float_t > mcshwr_MotherstartX
std::vector< Float_t > StartE_tpcAV
void SetShowerAddresses(size_t iShower)
bool hasPhotonInfo() const
Returns whether we have photon data.
float fwdLogLikelihood() const
minimum negative log likelihood value from fit assuming a forward track direction ...
Definition: MCSFitResult.h:35
double E() const
Definition: MCStep.h:49
std::vector< Float_t > mcshwr_StartDirX
PFParticleData_t< Int_t > pfp_pdgCode
the preliminary estimate of the PFParticle type using the PDG code
Class def header for MCShower data container.
std::vector< Float_t > mcshwr_endX
unsigned int MotherTrackID() const
Definition: MCShower.h:59
Class for Maximum Likelihood fit of Multiple Coulomb Scattering angles between segments within a Trac...
double Vz(const int i=0) const
Definition: MCParticle.h:223
std::vector< Float_t > mctrk_MotherstartX
const std::string & Process() const
Definition: MCShower.h:54
double Pz() const
Definition: MCStep.h:48
constexpr int kMaxNDaughtersPerPFP
std::vector< Float_t > EndPz_tpcAV
std::vector< art::Ptr< recob::Vertex > > VertexVector
std::vector< Float_t > thetaend_tpcAV
EventNumber_t event() const
Definition: EventID.h:116
Point_t const & End() const
Definition: Track.h:125
void CheckData(std::string caller) const
Helper function: throws if no data structure is available.
const MCStep & MotherStart() const
Definition: MCShower.h:61
Access the description of detector geometry.
Declaration of basic channel signal object.
std::vector< Float_t > StartPointy
detail::Node< FrameID, bool > PlaneID
Definition: CRTID.h:125
constexpr int kMaxChannels
const MCStep & Start() const
Definition: MCTrack.h:44
bool fSaveMCTrackInfo
whether to extract and save MC Shower information
bool hasPFParticleInfo() const
Returns whether we have PFParticle data.
std::vector< Float_t > mctrk_AncestorendY
std::vector< std::string > mcshwr_MotherProcess
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
double X() const
Definition: MCStep.h:42
void ResizeMCTrack(int nMCTracks)
Resize the data strutcure for MC Tracks.
std::size_t getView(std::string const &moduleLabel, std::string const &productInstanceName, std::string const &processName, std::vector< ELEMENT const * > &result) const
Definition: DataViewImpl.h:500
constexpr int kMaxTrackHits
constexpr int kNplanes
std::vector< Float_t > mcshwr_AncestorstartZ
size_t MaxPFParticles
maximum number of storable PFParticles
std::vector< std::string > processname
std::vector< art::Ptr< recob::Cluster > > ClusterVector
unsigned int NHits() const
Number of hits in the cluster.
Definition: Cluster.h:275
unsigned int TrackID() const
Definition: MCTrack.h:42
bool NeutrinoSet() const
Definition: MCTruth.h:78
AnaRootParserDataStruct::SubRunData_t SubRunData
std::vector< Float_t > EndE_drifted
TCEvent evt
Definition: DataStructs.cxx:7
ShowerData_t< Float_t > shwr_startdcosx
X directional cosine at start of shower.
int AncestorPdgCode() const
Definition: MCShower.h:64
float fwdMomentum() const
momentum value from fit assuming a forward track direction
Definition: MCSFitResult.h:29
Contains ROOTTreeCode<>::code, ROOT tree character for branch of type T.
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:297
const TrackDataStruct & GetTrackerData(size_t iTracker) const
std::map< std::string, double > mvaOutput
Definition: MVAPIDResult.h:27
void ResizeMCShower(int nMCShowers)
Resize the data strutcure for MC Showers.
AnaRootParser(fhicl::ParameterSet const &pset)
float EndAngle() const
Returns the ending angle of the cluster.
Definition: Cluster.h:519
AuxDetMCData_t< Float_t > CombinedEnergyDep
Sum energy of all particles with this trackID (+ID or -ID) in AuxDet.
void ResizeCry(int nPrimaries)
Resize the data strutcure for Cry primaries.
std::vector< Float_t > StartPointy_tpcAV
std::vector< Float_t > mcshwr_endY
std::vector< Int_t > SEDTPCAVNumPhotons
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:85
std::vector< UShort_t > NAuxDets
Number of AuxDets crossed by this particle.
std::vector< Float_t > StartPz_tpcAV
AuxDetMCData_t< Float_t > entryY
Entry Y position of particle into AuxDet.
recob::tracking::Plane Plane
Definition: TrackState.h:17
static constexpr double sr
Definition: Units.h:166
QuadExpr operator*(double v, const QuadExpr &e)
Definition: QuadExpr.h:39
void SetAddresses(TTree *pTree, std::string tracker, bool isCosmics)
void analyze(const art::Event &evt)
read access to event
constexpr int kMaxReadoutTicksInAllChannels
ShowerDataStruct const & GetShowerData(size_t iShower) const
helper function for LArPandoraInterface producer module
AuxDetMCData_t< Float_t > entryT
Entry T position of particle into AuxDet.
float StartTick() const
Returns the tick coordinate of the start of the cluster.
Definition: Cluster.h:297
std::string fCosmicClusterTaggerAssocLabel
int bool
Definition: qglobal.h:345
std::vector< Int_t > genie_primaries_pdg
std::vector< std::string > fTrackModuleLabel
std::vector< std::string > mctrk_MotherProcess
int ID() const
Definition: Shower.h:187
bool hasMCShowerInfo() const
Returns whether we have MCShower data.
AuxDetMCData_t< Float_t > exitZ
Exit Z position of particle out of AuxDet.
std::vector< BoxedArray< T[kNplanes]>> TrackPlaneData_t
PFParticleData_t< Short_t > pfp_showerID
the ID of the shower object corresponding to this PFParticle, if isShower
std::vector< Float_t > EndPx_drifted
double WireAngleToVertical(geo::View_t view, geo::TPCID const &tpcid) const
Returns the angle of the wires in the specified view from vertical.
EventID id() const
Definition: Event.cc:34
double Vy(const int i=0) const
Definition: MCParticle.h:222
const MCStep & AncestorEnd() const
Definition: MCTrack.h:59
static QCString str
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
Definition: Track.h:49
bool fSaveVertexInfo
whether to extract and save Track information
constexpr Point origin()
Returns a origin position with a point of the specified type.
Definition: geo_vectors.h:227
std::vector< Float_t > cry_StartPointy
size_t GetMaxSimEnergyDepositsTPCActive() const
Returns the number of SimEnergyDepositsTPCActive for which memory is allocated.
std::vector< Float_t > cry_StartPointt
Cosmic rays.
Definition: MCTruth.h:24
QTextStream & endl(QTextStream &s)
std::vector< Int_t > ParticleIDSimEnergyDepositsTPCActivePerParticle
size_t MaxTracks
maximum number of storable tracks
Event finding and building.
void beginSubRun(const art::SubRun &sr)
std::vector< Int_t > SEDTPCAVNumElectrons
float Integral() const
Returns the total charge of the cluster from hit shape.
Definition: Cluster.h:600
float EndWire() const
Returns the wire coordinate of the end of the cluster.
Definition: Cluster.h:329
std::vector< Float_t > phistart_tpcAV
constexpr int kMaxNClustersPerPFP
void ClearLocalData()
Clear all fields if this object (not the tracker algorithm data)
size_t GetMaxGEANTInAVparticles() const
Returns the number of GEANT particles in AV for which memory is allocated.
vertex reconstruction