LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
DirectHitParticleAssns_tool.cc
Go to the documentation of this file.
2 
10 
15 
17 
18 namespace t0 {
20  //
21  // Class: DirectHitParticleAssns
22  // Module Type: art tool
23  // File: DirectHitParticleAssns.h
24  //
25  // This provides MC truth information by using output
26  // reco Hit <--> MCParticle associations
27  //
28  // Configuration parameters:
29  //
30  // TruncMeanFraction - the fraction of waveform bins to discard when
31  //
32  // Created by Tracy Usher (usher@slac.stanford.edu) on November 21, 2017
33  //
35 
37  public:
43  explicit DirectHitParticleAssns(fhicl::ParameterSet const& pset);
44 
45  // provide for initialization
46  void reconfigure(fhicl::ParameterSet const& pset) override;
47 
52 
53  private:
54  std::vector<art::InputTag> fHitModuleLabelVec;
56 
57  struct TrackIDEinfo {
58  float E;
59  float NumElectrons;
60  };
61  std::unordered_map<int, TrackIDEinfo> fTrkIDECollector;
62  };
63 
64  //----------------------------------------------------------------------------
72  {
73  reconfigure(pset);
74 
75  // Report.
76  mf::LogInfo("DirectHitParticleAssns") << "Configured\n";
77  }
78 
79  //----------------------------------------------------------------------------
87  {
88  fMCParticleModuleLabel = pset.get<art::InputTag>("MCParticleLabel");
89  fHitModuleLabelVec = pset.get<std::vector<art::InputTag>>("HitModuleLabelVec");
90  }
91 
92  //----------------------------------------------------------------------------
100  HitParticleAssociations* hitPartAssns)
101  {
102  // This function handles the "direct" creation of hit<-->MCParticle associations through use of the BackTracker
103  //
104  auto mcpartHandle = evt.getValidHandle<std::vector<simb::MCParticle>>(fMCParticleModuleLabel);
105 
106  // Access art services...
109 
110  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
111 
112  // Loop over input hit producer labels
113  for (const auto& inputTag : fHitModuleLabelVec) {
115  evt.getByLabel(inputTag, hitListHandle);
116 
117  if (!hitListHandle.isValid()) {
118  mf::LogInfo("DirectHitParticleAssns")
119  << "InputTag not associating to valid hit collection, tag: " << inputTag << "\n";
120  continue;
121  }
122 
124  std::unordered_map<int, int>
125  trkid_lookup; //indexed by geant4trkid, delivers MC particle location
126 
127  auto const& hitList(*hitListHandle);
128  auto const& mcpartList(*mcpartHandle);
129 
130  for (size_t i_h = 0; i_h < hitList.size(); ++i_h) {
131  art::Ptr<recob::Hit> hitPtr(hitListHandle, i_h);
132 
133  auto trkide_list = btService->HitToTrackIDEs(clockData, hitPtr);
134 
135  double maxe(-1.);
136  double tote(0.);
137  int maxtrkid(-1);
138  double maxn(-1.);
139  double totn(0.);
140  int maxntrkid(-1);
141 
142  fTrkIDECollector.clear();
143 
144  //for(auto const& t : trkide_list){
145  for (size_t i_t = 0; i_t < trkide_list.size(); ++i_t) {
146  auto const& t(trkide_list[i_t]);
147  fTrkIDECollector[t.trackID].E += t.energy;
148  tote += t.energy;
149  if (fTrkIDECollector[t.trackID].E > maxe) {
150  maxe = fTrkIDECollector[t.trackID].E;
151  maxtrkid = t.trackID;
152  }
153  fTrkIDECollector[t.trackID].NumElectrons += t.numElectrons;
154  totn += t.numElectrons;
155  if (fTrkIDECollector[t.trackID].NumElectrons > maxn) {
156  maxn = fTrkIDECollector[t.trackID].NumElectrons;
157  maxntrkid = t.trackID;
158  }
159 
160  //if not found, find mc particle...
161  if (trkid_lookup.find(t.trackID) == trkid_lookup.end()) {
162  size_t i_p = 0;
163  while (i_p < mcpartList.size()) {
164  if (mcpartList[i_p].TrackId() == abs(t.trackID)) {
165  trkid_lookup[t.trackID] = (int)i_p;
166  break;
167  }
168  ++i_p;
169  }
170  if (i_p == mcpartList.size()) trkid_lookup[t.trackID] = -1;
171  }
172  }
173  //end loop on TrackIDs
174 
175  //now find the mcparticle and loop back through ...
176  for (auto const& t : fTrkIDECollector) {
177  int mcpart_i = trkid_lookup[t.first];
178  if (mcpart_i == -1) continue; //no mcparticle here
179  art::Ptr<simb::MCParticle> mcpartPtr(mcpartHandle, mcpart_i);
180  bthmd.ideFraction = t.second.E / tote;
181  bthmd.isMaxIDE = (t.first == maxtrkid);
182  bthmd.ideNFraction = t.second.NumElectrons / totn;
183  bthmd.isMaxIDEN = (t.first == maxntrkid);
184  bthmd.energy = t.second.E;
185  bthmd.numElectrons = t.second.NumElectrons;
186  hitPartAssns->addSingle(mcpartPtr, hitPtr, bthmd);
187  }
188 
189  } //end loop on hits
190  } // end loop on producers
191 
192  return;
193  }
194 
195  //----------------------------------------------------------------------------
196 
198 }
code to link reconstructed objects back to the MC truth information
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
std::unordered_map< int, TrackIDEinfo > fTrkIDECollector
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
Declaration of signal hit object.
constexpr auto abs(T v)
Returns the absolute value of the argument.
Particle class.
void CreateHitParticleAssociations(art::Event &, HitParticleAssociations *) override
This rebuilds the internal maps.
DirectHitParticleAssns(fhicl::ParameterSet const &pset)
Constructor.
bool isValid() const noexcept
Definition: Handle.h:203
T get(std::string const &key) const
Definition: ParameterSet.h:314
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
std::vector< art::InputTag > fHitModuleLabelVec
void addSingle(Ptr< left_t > const &left, Ptr< right_t > const &right, data_t const &data)
Definition: Assns.h:549
void reconfigure(fhicl::ParameterSet const &pset) override
TCEvent evt
Definition: DataStructs.cxx:8