All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MCTrackRecoAlg.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // MCTrackRecoAlg source
4 //
5 // dEdx and dQdx Estimates Added by Joseph Zennamo (jaz8600@fnal.gov)
6 //
7 ////////////////////////////////////////////////////////////////////////
8 
9 #include "MCTrackRecoAlg.h"
10 #include <iostream>
11 
12 #include "fhiclcpp/ParameterSet.h" // for ParameterSet
13 #include "cetlib_except/exception.h"
14 
15 #include "larcoreobj/SimpleTypesAndConstants/geo_types.h" // for PlaneID
16 #include "lardataobj/MCBase/MCLimits.h" // for kINVALID_UINT
17 #include "lardataobj/MCBase/MCStep.h" // for MCStep
18 #include "lardataobj/MCBase/MCTrack.h" // for MCTrack
19 #include "larsim/MCSTReco/MCRecoEdep.h" // for MCEdep
20 #include "larsim/MCSTReco/MCRecoPart.h" // for MCMiniPart
21 
22 namespace sim {
23 
24  //##################################################################
25  MCTrackRecoAlg::MCTrackRecoAlg(fhicl::ParameterSet const& pset)
26  //##################################################################
27  {
28  fDebugMode = pset.get<bool>("DebugMode");
29  }
30 
31  std::unique_ptr<std::vector<sim::MCTrack>> MCTrackRecoAlg::Reconstruct(MCRecoPart& part_v,
32  MCRecoEdep& edep_v)
33  {
34  auto result = std::make_unique<std::vector<sim::MCTrack>>();
35  auto& mctracks = *result;
36  auto pindex = details::createPlaneIndexMap();
37 
38  for(size_t i=0; i<part_v.size(); ++i) {
39  auto const& mini_part = part_v[i];
40  if( part_v._pdg_list.find(mini_part._pdgcode) == part_v._pdg_list.end() ) continue;
41 
42  ::sim::MCTrack mini_track;
43 
44  std::vector<double> dEdx;
45  std::vector<std::vector<double> > dQdx;
46  dQdx.resize(3);
47 
48  mini_track.Origin ( mini_part._origin );
49  mini_track.PdgCode ( mini_part._pdgcode );
50  mini_track.TrackID ( mini_part._track_id );
51  mini_track.Process ( mini_part._process );
52  mini_track.Start ( MCStep( mini_part._start_vtx, mini_part._start_mom ) );
53  mini_track.End ( MCStep( mini_part._end_vtx, mini_part._end_mom ) );
54 
55  unsigned int mother_track = part_v.MotherTrackID(i);
56  unsigned int ancestor_track = part_v.AncestorTrackID(i);
57 
58  if(mother_track == kINVALID_UINT || ancestor_track == kINVALID_UINT)
59 
60  throw cet::exception(__FUNCTION__) << "LOGIC ERROR: mother/ancestor track ID is invalid!";
61 
62  MCMiniPart mother_part;
63  MCMiniPart ancestor_part;
64 
65  unsigned int mother_index = part_v.TrackToParticleIndex(mother_track);
66  unsigned int ancestor_index = part_v.TrackToParticleIndex(ancestor_track);
67 
68  if(mother_index != kINVALID_UINT) mother_part = part_v[mother_index];
69  else mother_part._track_id = mother_track;
70 
71  if(ancestor_index != kINVALID_UINT) ancestor_part = part_v[ancestor_index];
72  else ancestor_part._track_id = ancestor_track;
73 
74  mini_track.MotherPdgCode ( mother_part._pdgcode );
75  mini_track.MotherTrackID ( mother_part._track_id );
76  mini_track.MotherProcess ( mother_part._process );
77  mini_track.MotherStart ( MCStep( mother_part._start_vtx, mother_part._start_mom ) );
78  mini_track.MotherEnd ( MCStep( mother_part._end_vtx, mother_part._end_mom ) );
79 
80  mini_track.AncestorPdgCode ( ancestor_part._pdgcode );
81  mini_track.AncestorTrackID ( ancestor_part._track_id );
82  mini_track.AncestorProcess ( ancestor_part._process );
83  mini_track.AncestorStart ( MCStep( ancestor_part._start_vtx, ancestor_part._start_mom ) );
84  mini_track.AncestorEnd ( MCStep( ancestor_part._end_vtx, ancestor_part._end_mom ) );
85 
86 
87  // Fill trajectory points
88 
89  for(auto const& vtx_mom : mini_part._det_path){
90  mini_track.push_back(MCStep(vtx_mom.first,vtx_mom.second));
91  }
92 
93  // No calorimetry for zero length tracks...
94  // JZ : I think we should remove zero length MCTracks because I do not see their utility
95  // JZ : Someone could make this a fcl parameter, I did not
96  if(mini_track.size() == 0){
97  mctracks.push_back(mini_track);
98  continue;
99  }
100 
101  auto const& edep_index = edep_v.TrackToEdepIndex(mini_part._track_id);
102  if(edep_index < 0 ) continue;
103  auto const& edeps = edep_v.GetEdepArrayAt(edep_index);
104 
105  //int n = 0; // unused
106 
107  for(auto const& step_trk : mini_track){
108 
109  if( int(&step_trk - &mini_track[0])+1 == int(mini_track.size()) ){ //annoying way to check if this is last step
110  continue;}
111 
112 
113  auto const& nxt_step_trk = mini_track.at(int(&step_trk - &mini_track[0])+1);
114 
115  //Defining the track step-by-step dEdx and dQdx
116 
117  //Find the distance between two adjacent MCSteps
118  double dist = sqrt(pow(step_trk.X() - nxt_step_trk.X(),2) +
119  pow(step_trk.Y() - nxt_step_trk.Y(),2) +
120  pow(step_trk.Z() - nxt_step_trk.Z(),2));
121 
122  //Make a plane at the step pointed at the next step
123 
124  //Need to define a plane through the first MCStep with a normal along the momentum vector of the step
125  //The plane will be defined in the typical way:
126  // a*x + b*y + c*z + d = 0
127  // where, a = dir_x, b = dir_y, c = dir_z, d = - (a*x_0+b*y_0+c*z_0)
128  // then the *signed* distance of any point (x_1, y_1, z_1) from this plane is:
129  // D = (a*x_1 + b*y_1 + c*z_1 + d )/sqrt( pow(a,2) + pow(b,2) + pow(c,2))
130 
131  double a = 0, b = 0, c = 0, d = 0;
132  a = nxt_step_trk.X() - step_trk.X();
133  b = nxt_step_trk.Y() - step_trk.Y();
134  c = nxt_step_trk.Z() - step_trk.Z();
135  d = -1*(a*step_trk.X() + b*step_trk.Y() + c*step_trk.Z());
136 
137  //Make a line connecting the two points and find the distance from that line
138  //
139  // [A dot B]^2 [A dot B]^2
140  // distance^2 = A^2 - 2* ____________ + ______________
141  // B^2 B^2
142  // Test point == x_0
143  // First Step == x_1
144  // Next step == x_2
145  // A = x_1 - x_0
146  // B = x_2 - x_1
147 
148  // 'B' definition
149  TVector3 B(nxt_step_trk.Position().X() - step_trk.Position().X(),
150  nxt_step_trk.Position().Y() - step_trk.Position().Y(),
151  nxt_step_trk.Position().Z() - step_trk.Position().Z());
152 
153 
154  //Initialize the step-by-step dEdx and dQdx containers
155  double step_dedx = 0;
156  std::vector<double> step_dqdx;
157  step_dqdx.resize(3);
158 
159  //Iterate through all the energy deposition points
160  for(auto const& edep : edeps){
161  // 'x_0' definition
162  TVector3 x_0(edep.pos._x, edep.pos._y, edep.pos._z);
163  // 'A' definition
164  TVector3 A(step_trk.Position().X() - x_0.X(),
165  step_trk.Position().Y() - x_0.Y(),
166  step_trk.Position().Z() - x_0.Z());
167 
168  // Distance from the line connecting x_1 and x_2
169  double LineDist = 0;
170 
171  if(B.Mag2() != 0){
172  LineDist = sqrt(A.Mag2() - 2*pow(A*B,2)/B.Mag2() + pow(A*B,2)/B.Mag2());
173  }
174  else{LineDist = 0;}
175 
176  //Planar Distance and Radial Line Distance Cuts
177  // Add in a voxel before and after to account for MCSteps
178  // the line distance allows for 1mm GEANT multiple columb scattering correction,
179  // small compared to average MCStep-to-MCStep distance
180  if( (a*edep.pos._x + b*edep.pos._y + c*edep.pos._z + d)/sqrt( pow(a,2) + pow(b,2) + pow(c,2)) <= dist + 0.03 &&
181  (a*edep.pos._x + b*edep.pos._y + c*edep.pos._z + d)/sqrt( pow(a,2) + pow(b,2) + pow(c,2)) >= 0 - 0.03 &&
182  LineDist < 0.1){
183 
184  //dEdx Calculation
185  int npid = 0;
186  double engy = 0;
187 
188  for(auto const& pid_energy : edep.deps){
189  engy += pid_energy.energy;
190  npid++;
191  }
192 
193  if(npid != 0){
194  engy /= npid;}
195  else{engy = 0;}
196 
197  step_dedx += engy;
198  auto const pid = edep.pid;
199  auto q_i = pindex.find(pid);
200  if(q_i != pindex.end())
201  step_dqdx[pid.Plane] += (double)(edep.deps[pindex[pid]].charge);
202  }
203  }
204 
205  // Normalize to the 3D distance between the MCSteps
206 
207  //Disregard any energy deposition when 2 MCSteps are separated less than the voxel size
208  if(dist > 0.03){
209  step_dedx /= dist;
210  step_dqdx[0] /= dist;
211  step_dqdx[1] /= dist;
212  step_dqdx[2] /= dist;
213  }
214  else{
215  step_dedx = 0;
216  step_dqdx[0] = 0;
217  step_dqdx[1] = 0;
218  step_dqdx[2] = 0;
219  }
220 
221  // Build the vector(s) to add to data product
222  dEdx.push_back(step_dedx);
223  dQdx[0].push_back(step_dqdx[0]);
224  dQdx[1].push_back(step_dqdx[1]);
225  dQdx[2].push_back(step_dqdx[2]);
226 
227 
228 
229  }
230 
231  //Add calorimetry to the data product
232  mini_track.dEdx(dEdx);
233  mini_track.dQdx(dQdx);
234 
235 
236  mctracks.push_back(mini_track);
237 
238 
239 
240  }
241 
242  if(fDebugMode) {
243 
244  for(auto const& prof : mctracks) {
245 
246  std::cout
247 
248  << Form(" Track particle: PDG=%d : Track ID=%d Start @ (%g,%g,%g,%g) with Momentum (%g,%g,%g,%g)",
249  prof.PdgCode(),prof.TrackID(),
250  prof.Start().X(),prof.Start().Y(),prof.Start().Z(),prof.Start().T(),
251  prof.Start().Px(),prof.Start().Py(),prof.Start().Pz(),prof.Start().E())
252  << std::endl
253  << Form(" Mother particle: PDG=%d : Track ID=%d Start @ (%g,%g,%g,%g) with Momentum (%g,%g,%g,%g)",
254  prof.MotherPdgCode(),prof.MotherTrackID(),
255  prof.MotherStart().X(),prof.MotherStart().Y(),prof.MotherStart().Z(),prof.MotherStart().T(),
256  prof.MotherStart().Px(),prof.MotherStart().Py(),prof.MotherStart().Pz(),prof.MotherStart().E())
257  << std::endl
258  << Form(" Ancestor particle: PDG=%d : Track ID=%d Start @ (%g,%g,%g,%g) with Momentum (%g,%g,%g,%g)",
259  prof.AncestorPdgCode(),prof.AncestorTrackID(),
260  prof.AncestorStart().X(),prof.AncestorStart().Y(),prof.AncestorStart().Z(),prof.AncestorStart().T(),
261  prof.AncestorStart().Px(),prof.AncestorStart().Py(),prof.AncestorStart().Pz(),prof.AncestorStart().E())
262  << std::endl
263  << Form(" ... with %zu trajectory points!",prof.size())
264  << std::endl;
265 
266  if(prof.size()) {
267  std::cout
268  << Form(" Start @ (%g,%g,%g,%g) with Momentum (%g,%g,%g,%g)",
269  prof[0].X(), prof[0].Y(), prof[0].Z(), prof[0].T(),
270  prof[0].Px(), prof[0].Py(), prof[0].Pz(), prof[0].E())
271  << std::endl
272  << Form(" End @ (%g,%g,%g,%g) with Momentum (%g,%g,%g,%g)",
273  (*prof.rbegin()).X(), (*prof.rbegin()).Y(), (*prof.rbegin()).Z(), (*prof.rbegin()).T(),
274  (*prof.rbegin()).Px(), (*prof.rbegin()).Py(), (*prof.rbegin()).Pz(), (*prof.rbegin()).E())
275  << std::endl;
276  }
277  }
278 
279  std::cout<<std::endl<<std::endl;
280  }
281  return result;
282  }
283 }
std::string _process
Definition: MCRecoPart.h:32
simb::Origin_t Origin() const
Definition: MCTrack.h:40
const std::string & AncestorProcess() const
Definition: MCTrack.h:57
const MCStep & MotherEnd() const
Definition: MCTrack.h:53
unsigned int AncestorTrackID() const
Definition: MCTrack.h:56
std::map< geo::PlaneID, size_t > createPlaneIndexMap()
Definition: MCRecoEdep.cxx:26
unsigned int MotherTrackID(const unsigned int part_index) const
Definition: MCRecoPart.cxx:42
process_name E
const std::vector< sim::MCEdep > & GetEdepArrayAt(size_t edep_index) const
Returns a vector of MCEdep object at the given index.
Definition: MCRecoEdep.cxx:49
then echo echo For and will not be changed by echo further linking echo echo B echo The symbol is in the uninitialized data multiple common symbols may appear with the echo same name If the symbol is defined the common echo symbols are treated as undefined references For more echo details on common see the discussion of warn common echo in *Note Linker see the discussion of warn common echo in *Note Linker such as a global int variable echo as opposed to a large global array echo echo I echo The symbol is an indirect reference to another symbol This echo is a GNU extension to the a out object file format which is echo rarely used echo echo N echo The symbol is a debugging symbol echo echo R echo The symbol is in a read only data section echo echo S echo The symbol is in an uninitialized data section for small echo objects echo echo T echo The symbol is in the the normal defined echo symbol is used with no error When a weak undefined symbol echo is linked and the symbol is not the value of the echo weak symbol becomes zero with no error echo echo W echo The symbol is a weak symbol that has not been specifically echo tagged as a weak object symbol When a weak defined symbol echo is linked with a normal defined the normal defined echo symbol is used with no error When a weak undefined symbol echo is linked and the symbol is not the value of the echo weak symbol becomes zero with no error echo echo echo The symbol is a stabs symbol in an a out object file In echo this the next values printed are the stabs other echo the stabs desc and the stab type Stabs symbols are echo used to hold debugging information For more echo see *Note or object file format specific echo echo For Mac OS X
int AncestorPdgCode() const
Definition: MCTrack.h:55
TLorentzVector _start_vtx
Definition: MCRecoPart.h:36
const MCStep & End() const
Definition: MCTrack.h:45
Class def header for mcstep data container.
unsigned int MotherTrackID() const
Definition: MCTrack.h:50
TLorentzVector _start_mom
Definition: MCRecoPart.h:37
process_name gaushit a
unsigned int AncestorTrackID(const unsigned int part_index)
Definition: MCRecoPart.cxx:68
int TrackToEdepIndex(unsigned int track_id) const
Converts a track ID to MCEdep array index. Returns -1 if no corresponding array found ...
Definition: MCRecoEdep.h:113
TLorentzVector _end_mom
Definition: MCRecoPart.h:39
TLorentzVector _end_vtx
Definition: MCRecoPart.h:38
Class def header for mctrack data container.
const MCStep & AncestorStart() const
Definition: MCTrack.h:58
Definition of data types for geometry description.
float dEdx(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const TCSlice &slc, TP3D &tp3d)
Definition: PFPUtils.cxx:2687
int PdgCode() const
Definition: MCTrack.h:41
MCTrackRecoAlg(fhicl::ParameterSet const &pset)
Default constructor with fhicl parameters.
const MCStep & MotherStart() const
Definition: MCTrack.h:52
int MotherPdgCode() const
Definition: MCTrack.h:49
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
std::set< int > _pdg_list
PDG code list for which particle&#39;s trajectory within the detector is saved.
Definition: MCRecoPart.h:148
const std::string & Process() const
Definition: MCTrack.h:43
const std::string & MotherProcess() const
Definition: MCTrack.h:51
const unsigned int kINVALID_UINT
Definition: MCLimits.h:14
const MCStep & Start() const
Definition: MCTrack.h:44
unsigned int _track_id
Definition: MCRecoPart.h:31
std::unique_ptr< std::vector< sim::MCTrack > > Reconstruct(MCRecoPart &part_v, MCRecoEdep &edep_v)
unsigned int TrackID() const
Definition: MCTrack.h:42
float A
Definition: dedx.py:137
unsigned int TrackToParticleIndex(const unsigned int track_id) const
Definition: MCRecoPart.h:130
const MCStep & AncestorEnd() const
Definition: MCTrack.h:59
BEGIN_PROLOG could also be cout