LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
PhotonBackTracker.cc
Go to the documentation of this file.
1 //
3 // \file PhotonBackTracker.cc
4 // \brief The functions needed for the PhotonBackTracker class needed by the
5 // PhotonBackTrackerService in order to connect truth information with
6 // reconstruction.
7 // \author jason.stock@mines.sdsmt.edu
8 //
9 // Based on the original BackTracker by brebel@fnal.gov
10 //
12 //
13 //TODO: Impliment alternate backtracking scheme developed by T. Usher
14 //TODO: OpChanToOpDetSDPs (Expanded Clone of OpDetNumToOpDetSDPs
15 //
17 
18 //Includes
21 
22 //CPP
23 #include <map>
24 
25 //Framework
27 
28 //LArSoft
31 
32 namespace cheat {
33 
34  //----------------------------------------------------------------
36  const cheat::ParticleInventory* partInv,
37  const geo::GeometryCore* geom) //,
38  // const detinfo::DetectorClocks* detClock)
39  : fPartInv(partInv)
40  , fGeom(geom)
41  ,
42  // fDetClocks (detClock),
43  fDelay(config.Delay())
44  , fG4ModuleLabel(config.G4ModuleLabel())
45  , fG4ModuleLabels(config.G4ModuleLabels())
46  , fOpHitLabel(config.OpHitLabel())
47  , fOpFlashLabel(config.OpFlashLabel())
48  ,
49  //fWavLabel(config.WavLabel()),
50  fMinOpHitEnergyFraction(config.MinOpHitEnergyFraction())
51  {}
52 
53  //----------------------------------------------------------------
55  const cheat::ParticleInventory* partInv,
56  const geo::GeometryCore* geom) //,
57  // const detinfo::DetectorClocks* detClock)
58  : fPartInv(partInv)
59  , fGeom(geom)
60  ,
61  // fDetClocks(detClock),
62  fDelay(pSet.get<double>("Delay"))
63  , fG4ModuleLabel(pSet.get<art::InputTag>("G4ModuleLabel", "largeant"))
64  , fG4ModuleLabels(pSet.get<std::vector<art::InputTag>>("G4ModuleLabels", {}))
65  , fOpHitLabel(pSet.get<art::InputTag>("OpHitLabel", "ophit"))
66  , fOpFlashLabel(pSet.get<art::InputTag>("OpFlashLabel", "opflash"))
67  , fMinOpHitEnergyFraction(pSet.get<double>("MinimumOpHitEnergyFraction", 0.1))
68  {}
69 
70  //----------------------------------------------------------------
72  {
73  return this->fDelay;
74  }
75 
76  //----------------------------------------------------------------
78  {
79  priv_OpDetBTRs.clear();
80  priv_OpFlashToOpHits.clear();
81  }
82 
83  //----------------------------------------------------------------
85  {
86  return !(priv_OpDetBTRs.empty());
87  }
88 
89  //----------------------------------------------------------------
91  {
92  return !(priv_OpFlashToOpHits.empty());
93  }
94 
95  //----------------------------------------------------------------
96  const std::vector<art::Ptr<sim::OpDetBacktrackerRecord>>& PhotonBackTracker::OpDetBTRs()
97  {
98  return priv_OpDetBTRs;
99  }
100 
101  //----------------------------------------------------------------
102  const std::vector<const sim::SDP*> PhotonBackTracker::TrackIdToSimSDPs_Ps(int const& id)
103  {
104  std::vector<const sim::SDP*> sdp_Ps;
105  for (size_t odet = 0; odet < priv_OpDetBTRs.size(); ++odet) {
106  const auto& pdTimeSDPmap = priv_OpDetBTRs[odet]->timePDclockSDPsMap();
107  for (auto mapitr = pdTimeSDPmap.begin(); mapitr != pdTimeSDPmap.end(); mapitr++) {
108  std::vector<sim::SDP> const& sdpvec = (*mapitr).second;
109  for (size_t iv = 0; iv < sdpvec.size(); ++iv) {
110  // const sim::SDP* const sdp_P = &sdpvec[iv];
111  if (abs(sdpvec[iv].trackID) == id) sdp_Ps.push_back(&(sdpvec[iv]));
112  }
113  } // end loop over map from sim::OpDetBacktrackerRecord
114 
115  } // end loop over sim::OpDetBacktrackerRecords
116  return sdp_Ps;
117  }
118 
119  //----------------------------------------------------------------
120  const std::vector<const sim::SDP*> PhotonBackTracker::TrackIdToSimSDPs_Ps(int const& id,
121  geo::View_t const& view)
122  {
123  throw cet::exception("PhotonBackTracker")
124  << "PhotonBackTracker is not equiped to handle geo::Views.";
125  }
126 
127  //----------------------------------------------------------------
129  int const& opDetNum) const
130  {
132  for (size_t sc = 0; sc < priv_OpDetBTRs.size(); ++sc) {
133  //This could become a bug. What if it occurs twice (shouldn't happen in correct records, but still, no error handeling included for the situation
134  if (priv_OpDetBTRs.at(sc)->OpDetNum() == opDetNum) opDet = priv_OpDetBTRs.at(sc);
135  }
136  if (!opDet) {
137  throw cet::exception("PhotonBackTracker2") << "No sim:: OpDetBacktrackerRecord corresponding "
138  << "to opDetNum: " << opDetNum << "\n";
139  }
140  return opDet;
141  }
142 
143  //----------------------------------------------------------------
144  const std::vector<sim::TrackSDP> PhotonBackTracker::OpDetToTrackSDPs(
145  int const& OpDetNum,
146  double const& opHit_start_time,
147  double const& opHit_end_time) const
148  {
149  std::vector<sim::TrackSDP> tSDPs;
150  double totalE = 0;
151  try {
152  const art::Ptr<sim::OpDetBacktrackerRecord> opDetBTR = this->FindOpDetBTR(OpDetNum);
153  // ( fGeom->OpDetFromOpChannel(channel) );
154  std::vector<sim::SDP> simSDPs =
155  opDetBTR->TrackIDsAndEnergies(opHit_start_time, opHit_end_time);
156  for (size_t e = 0; e < simSDPs.size(); ++e)
157  totalE += simSDPs[e].energy;
158  if (totalE < 1.e-5) totalE = 1.;
159  for (size_t e = 0; e < simSDPs.size(); ++e) {
160  if (simSDPs[e].trackID == sim::NoParticleId) continue;
161  sim::TrackSDP info;
162  info.trackID = std::abs(simSDPs[e].trackID);
163  info.energyFrac = simSDPs[e].energy / totalE;
164  info.energy = simSDPs[e].energy;
165  tSDPs.push_back(info);
166  }
167  }
168  catch (
169  cet::exception const&
170  e) { //This needs to go. Make it specific if there is a really an exception we would like to catch.
171  mf::LogWarning("PhotonBackTracker") << "Exception caught\n" << e;
172  }
173  return tSDPs;
174  }
175 
176  //----------------------------------------------------------------
177  const std::vector<sim::TrackSDP> PhotonBackTracker::OpHitToTrackSDPs(
178  art::Ptr<recob::OpHit> const& opHit_P) const
179  {
180  auto OpDetNum = fGeom->OpDetFromOpChannel(opHit_P->OpChannel());
181  const double pTime = opHit_P->PeakTime();
182  const double pWidth = opHit_P->Width();
183  const double start = (pTime - pWidth) * 1000 - fDelay;
184  const double end = (pTime + pWidth) * 1000 - fDelay;
185  return this->OpDetToTrackSDPs(OpDetNum, start, end);
186  }
187 
188  //----------------------------------------------------------------
189  const std::vector<sim::TrackSDP> PhotonBackTracker::OpHitToTrackSDPs(
190  recob::OpHit const& opHit) const
191  {
192  auto OpDetNum = fGeom->OpDetFromOpChannel(opHit.OpChannel());
193  const double pTime = opHit.PeakTime();
194  const double pWidth = opHit.Width();
195  const double start = (pTime - pWidth) * 1000 - fDelay;
196  const double end = (pTime + pWidth) * 1000 - fDelay;
197  return this->OpDetToTrackSDPs(OpDetNum, start, end);
198  }
199 
200  //----------------------------------------------------------------
201  const std::vector<int> PhotonBackTracker::OpHitToTrackIds(recob::OpHit const& opHit) const
202  {
203  std::vector<int> retVec;
204  for (auto const trackSDP : this->OpHitToTrackSDPs(opHit)) {
205  retVec.push_back(trackSDP.trackID);
206  }
207  return retVec;
208  }
209 
210  //----------------------------------------------------------------
211  const std::vector<int> PhotonBackTracker::OpHitToTrackIds(
212  art::Ptr<recob::OpHit> const& opHit) const
213  {
214  return this->OpHitToTrackIds(*opHit);
215  }
216 
217  //----------------------------------------------------------------
218  const std::vector<int> PhotonBackTracker::OpHitToEveTrackIds(recob::OpHit const& opHit)
219  { /*NEW*/ /*COMPLETE*/
220  std::vector<int> retVec;
221  for (auto const trackSDP : this->OpHitToEveTrackSDPs(opHit)) {
222  retVec.push_back(trackSDP.trackID);
223  }
224  return retVec;
225  }
226 
227  //----------------------------------------------------------------
229  art::Ptr<recob::OpHit> const& opHit_P)
230  { /*NEW*/ /*COMPLETE*/
231  return this->OpHitToEveTrackIds(*opHit_P);
232  }
233 
234  //----------------------------------------------------------------
235  const std::vector<sim::TrackSDP> PhotonBackTracker::OpHitToEveTrackSDPs(
236  art::Ptr<recob::OpHit> const& opHit_P) const
237  {
238  return this->OpHitToEveTrackSDPs(*opHit_P);
239  }
240 
241  //----------------------------------------------------------------
242  const std::vector<sim::TrackSDP> PhotonBackTracker::OpHitToEveTrackSDPs(
243  recob::OpHit const& opHit) const
244  {
245  std::vector<sim::TrackSDP> trackSDPs = this->OpHitToTrackSDPs(opHit);
246 
247  // make a map of evd ID values and fraction of energy represented by
248  // // that eve id in this opHit
249  std::map<int, float> eveIDtoEfrac;
250 
251  double totalE = 0.;
252  for (size_t t = 0; t < trackSDPs.size(); ++t) {
253  eveIDtoEfrac[(fPartInv->ParticleList()).EveId(trackSDPs[t].trackID)] += trackSDPs[t].energy;
254  totalE += trackSDPs[t].energy;
255  }
256 
257  // now fill the eveSDPs vector from the map
258  std::vector<sim::TrackSDP> eveSDPs;
259  eveSDPs.reserve(eveIDtoEfrac.size());
260  for (auto itr = eveIDtoEfrac.begin(); itr != eveIDtoEfrac.end(); itr++) {
261  sim::TrackSDP temp;
262  temp.trackID = (*itr).first;
263  temp.energyFrac = (*itr).second / totalE;
264  temp.energy = (*itr).second;
265  eveSDPs.push_back(std::move(temp));
266  }
267  return eveSDPs;
268  }
269 
270  //----------------------------------------------------------------
271  //TODO: Make a copy of this function that uses an allOpHits list.
272  const std::vector<art::Ptr<recob::OpHit>> PhotonBackTracker::TrackIdToOpHits_Ps(
273  int const& tkId,
274  std::vector<art::Ptr<recob::OpHit>> const& hitsIn)
275  {
276  //One would think we would want to have this function defined, and call this function in the std::vector<tkids> to opHits, but that would require more loops (and a higher overhead.) Instead, to provide this, we will just call the existing std::vector<tkids>ToOpHits with an input of 1.
277  std::vector<int> tkidFake(1, tkId);
278  //std::vector<art::Ptr<recob::OpHit>> retVec = (this->TrackIdsToOpHits_Ps(tkidFake, hitsIn)).at(0);
279  // return (this->TrackIdsToOpHits_Ps(tkidFake, hitsIn));
280  const std::vector<art::Ptr<recob::OpHit>> out =
281  (this->TrackIdsToOpHits_Ps(tkidFake, hitsIn)).at(0);
282  return out;
283  }
284 
285  //----------------------------------------------------------------
286  const std::vector<std::vector<art::Ptr<recob::OpHit>>> PhotonBackTracker::TrackIdsToOpHits_Ps(
287  std::vector<int> const& tkIds,
288  std::vector<art::Ptr<recob::OpHit>> const& hitsIn)
289  {
290  std::vector<std::pair<int, art::Ptr<recob::OpHit>>> opHitList;
291  for (auto itr = hitsIn.begin(); itr != hitsIn.end(); ++itr) {
292  art::Ptr<recob::OpHit> const& opHit = *itr;
293  auto OpDetNum = fGeom->OpDetFromOpChannel(opHit->OpChannel());
294  const double pTime = opHit->PeakTime(), pWidth = opHit->Width();
295  const double start = (pTime - pWidth) * 1000.0 - fDelay,
296  end = (pTime + pWidth) * 1000.0 - fDelay;
297  std::vector<sim::TrackSDP> tids = this->OpDetToTrackSDPs(OpDetNum, start, end);
298  //std::vector<sim::TrackSDP> tids = this->OpDetToTrackSDPs( opHit->OpChannel(), start, end);
299  for (auto itid = tids.begin(); itid != tids.end(); ++itid) {
300  for (auto itkid = tkIds.begin(); itkid != tkIds.end(); ++itkid) {
301  if (itid->trackID == *itkid) {
302  if (itid->energyFrac > fMinOpHitEnergyFraction)
303  opHitList.push_back(std::make_pair(*itkid, opHit));
304  }
305  } // itkid
306  } // itid
307  } // itr
308  // now build the truOpHits vector that will be returned to the caller
309  std::vector<std::vector<art::Ptr<recob::OpHit>>> truOpHits;
310  // temporary vector containing opHits assigned to one MC particle
311  std::vector<art::Ptr<recob::OpHit>> tmpOpHits;
312  for (auto itkid = tkIds.begin(); itkid != tkIds.end(); ++itkid) {
313  tmpOpHits.clear();
314  for (auto itr = opHitList.begin(); itr != opHitList.end(); ++itr) {
315  if (*itkid == (*itr).first) tmpOpHits.push_back((*itr).second);
316  }
317  truOpHits.push_back(tmpOpHits);
318  }
319  return truOpHits;
320  }
321 
322  //----------------------------------------------------------------
323  const std::vector<const sim::SDP*> PhotonBackTracker::OpHitToSimSDPs_Ps(
324  recob::OpHit const& opHit) const
325  {
326  std::vector<const sim::SDP*> retVec;
327  double fPeakTime = opHit.PeakTime();
328  double fWidth = opHit.Width();
330  ((fPeakTime - fWidth) * 1000.0) - fDelay;
331  sim::OpDetBacktrackerRecord::timePDclock_t end_time = ((fPeakTime + fWidth) * 1000.0) - fDelay;
332  if (start_time > end_time) { throw; }
333 
334  //BUG!!!fGeom->OpDetFromOpChannel(channel)
335  const std::vector<std::pair<double, std::vector<sim::SDP>>>& timeSDPMap =
337  ->timePDclockSDPsMap(); //Not guranteed to be sorted.
338  //const std::vector<std::pair<double, std::vector<sim::SDP>> >& timeSDPMap = (this->FindOpDetBTR(opHit.OpChannel()))->timePDclockSDPsMap(); //Not guranteed to be sorted.
339 
340  std::vector<const std::pair<double, std::vector<sim::SDP>>*> timePDclockSDPMap_SortedPointers;
341  for (auto& pair : timeSDPMap) {
342  timePDclockSDPMap_SortedPointers.push_back(&pair);
343  }
344  auto pairSort = [](auto& a, auto& b) { return a->first < b->first; };
345  if (!std::is_sorted(timePDclockSDPMap_SortedPointers.begin(),
346  timePDclockSDPMap_SortedPointers.end(),
347  pairSort)) {
348  std::sort(
349  timePDclockSDPMap_SortedPointers.begin(), timePDclockSDPMap_SortedPointers.end(), pairSort);
350  }
351 
352  //This section is a hack to make comparisons work right.
353  std::vector<sim::SDP> dummyVec;
354  std::pair<double, std::vector<sim::SDP>> start_timePair = std::make_pair(start_time, dummyVec);
355  std::pair<double, std::vector<sim::SDP>> end_timePair = std::make_pair(end_time, dummyVec);
356  auto start_timePair_P = &start_timePair;
357  auto end_timePair_P = &end_timePair;
358  //First interesting iterator.
359  auto mapFirst = std::lower_bound(timePDclockSDPMap_SortedPointers.begin(),
360  timePDclockSDPMap_SortedPointers.end(),
361  start_timePair_P,
362  pairSort);
363  //Last interesting iterator.
364  auto mapLast =
365  std::upper_bound(mapFirst, timePDclockSDPMap_SortedPointers.end(), end_timePair_P, pairSort);
366 
367  for (auto& mapitr = mapFirst; mapitr != mapLast; ++mapitr)
368  for (auto& sdp : (*mapitr)->second)
369  retVec.push_back(&sdp);
370 
371  return retVec;
372 
373  //sdps = FindOpDetBTR( geom->OpDetFromOpChannel(opHit. OpChannel()) )->TrackIDsAndEnergies(start_time, end_time);
374  // return (this->FindOpDetBTR( fGeom->OpDetFromOpChannel(opHit.OpChannel()) ))->TrackIDsAndEnergies(start_time, end_time);
375  }
376 
377  //----------------------------------------------------------------
378  const std::vector<const sim::SDP*> PhotonBackTracker::OpHitToSimSDPs_Ps(
379  art::Ptr<recob::OpHit> const& opHit_P) const
380  {
381  return this->OpHitToSimSDPs_Ps(*opHit_P);
382  }
383 
384  //----------------------------------------------------------------
385  const std::vector<double> PhotonBackTracker::SimSDPsToXYZ(
386  std::vector<sim::SDP> const& sdps) const&
387  {
388  std::vector<double> xyz(3, -999.);
389  double x = 0.;
390  double y = 0.;
391  double z = 0.;
392  double w = 0.;
393  // loop over photons.
394  for (auto const& sdp : sdps) {
395  double weight = sdp.numPhotons;
396  w += weight;
397  x += weight * sdp.x;
398  y += weight * sdp.y;
399  z += weight * sdp.z;
400  } // end loop over sim::SDPs
401  //If the sum of the weights is still zero, then fail to return a value.
402  //A hit with no contributing photons does't make sense.
403  if (w < 1.e-5)
404  throw cet::exception("PhotonBackTracker")
405  << "No sim::SDPs providing non-zero number of photons"
406  << " can't determine originating location from truth\n";
407  xyz[0] = x / w;
408  xyz[1] = y / w;
409  xyz[2] = z / w;
410  return xyz;
411  }
412 
413  //----------------------------------------------------------------
414  const std::vector<double> PhotonBackTracker::SimSDPsToXYZ(
415  std::vector<const sim::SDP*> const& sdps_Ps) const&
416  {
417  std::vector<double> xyz(3, -999.);
418  double x = 0.;
419  double y = 0.;
420  double z = 0.;
421  double w = 0.;
422  // loop over photons.
423  for (const sim::SDP* sdp_P : sdps_Ps) {
424  auto& sdp = *sdp_P;
425  double weight = sdp.numPhotons;
426  w += weight;
427  x += weight * sdp.x;
428  y += weight * sdp.y;
429  z += weight * sdp.z;
430  } // end loop over sim::SDPs
431  //If the sum of the weights is still zero, then fail to return a value.
432  //A hit with no contributing photons does't make sense.
433  if (w < 1.e-5)
434  throw cet::exception("PhotonBackTracker")
435  << "No sim::SDPs providing non-zero number of photons"
436  << " can't determine originating location from truth\n";
437  xyz[0] = x / w;
438  xyz[1] = y / w;
439  xyz[2] = z / w;
440  return xyz;
441  }
442 
443  //----------------------------------------------------------------
444  const std::vector<double> PhotonBackTracker::OpHitToXYZ(recob::OpHit const& opHit)
445  {
446  return SimSDPsToXYZ(this->OpHitToSimSDPs_Ps(opHit));
447  }
448 
449  //----------------------------------------------------------------
450  const std::vector<double> PhotonBackTracker::OpHitToXYZ(art::Ptr<recob::OpHit> const& opHit)
451  {
452  return SimSDPsToXYZ(this->OpHitToSimSDPs_Ps(*opHit));
453  }
454 
455  //----------------------------------------------------------------
456  //const std::vector< const sim::SDP* > PhotonBackTracker::OpHitToSimSDPs_Ps(recob::OpHit const& opHit)
457  // const std::vector< const sim::SDP* > PhotonBackTracker::OpHitsToSimSDPs_Ps(const std::vector< art::Ptr < recob::OpHit > >& opHits_Ps)
458  const std::vector<const sim::SDP*> PhotonBackTracker::OpHitsToSimSDPs_Ps(
459  std::vector<art::Ptr<recob::OpHit>> const& opHits_Ps) const
460  {
461  std::vector<const sim::SDP*> sdps_Ps;
462  for (auto opHit_P : opHits_Ps) {
463  std::vector<const sim::SDP*> to_add_sdps_Ps = this->OpHitToSimSDPs_Ps(opHit_P);
464  sdps_Ps.insert(sdps_Ps.end(), to_add_sdps_Ps.begin(), to_add_sdps_Ps.end());
465  }
466  return sdps_Ps;
467  }
468 
469  //----------------------------------------------------------------
470  const std::vector<double> PhotonBackTracker::OpHitsToXYZ(
471  std::vector<art::Ptr<recob::OpHit>> const& opHits_Ps) const
472  {
473  const std::vector<const sim::SDP*> SDPs_Ps = OpHitsToSimSDPs_Ps(opHits_Ps);
474  return this->SimSDPsToXYZ(SDPs_Ps);
475  }
476 
477  //----------------------------------------------------------------
478  const std::unordered_set<const sim::SDP*> PhotonBackTracker::OpHitToEveSimSDPs_Ps(
479  recob::OpHit const& opHit_P)
480  { /*NEW*/ /*COMPLETE*/
481  const std::vector<int> ids = this->OpHitToEveTrackIds(opHit_P);
482  std::unordered_set<const sim::SDP*> sdps;
483  for (auto const& id : ids) {
484  std::vector<const sim::SDP*> tmp_sdps = TrackIdToSimSDPs_Ps(id);
485  for (const sim::SDP* tmp_sdp : tmp_sdps) {
486  sdps.insert(tmp_sdp); //emplace not needed here.
487  }
488  }
489  return sdps;
490  }
491 
492  //----------------------------------------------------------------
493  const std::unordered_set<const sim::SDP*> PhotonBackTracker::OpHitToEveSimSDPs_Ps(
494  art::Ptr<recob::OpHit>& opHit)
495  { /*NEW*/ /*COMPLETE*/
496  const std::vector<int> ids = this->OpHitToEveTrackIds(opHit);
497  std::unordered_set<const sim::SDP*> sdps;
498  for (auto const& id : ids) {
499  std::vector<const sim::SDP*> tmp_sdps = TrackIdToSimSDPs_Ps(id);
500  for (const sim::SDP* tmp_sdp : tmp_sdps) {
501  sdps.insert(tmp_sdp); //emplace not needed here.
502  }
503  }
504  return sdps;
505  }
506 
507  //----------------------------------------------------------------
508  const std::set<int> PhotonBackTracker::GetSetOfEveIds() const
509  {
510  //std::set<int> out = fPartInv->GetSetOfEveIds();
511  return fPartInv->GetSetOfEveIds();
512  //return out;
513  }
514 
515  //----------------------------------------------------------------
516  const std::set<int> PhotonBackTracker::GetSetOfTrackIds() const
517  {
518  return fPartInv->GetSetOfTrackIds();
519  }
520 
521  //----------------------------------------------------------------
523  std::vector<art::Ptr<recob::OpHit>> const& opHits_Ps) const
524  {
525  std::set<int> eveIds;
526  for (auto const& opHit_P : opHits_Ps) {
527  const std::vector<sim::TrackSDP> sdps = this->OpHitToEveTrackSDPs(opHit_P);
528  for (auto const& sdp : sdps) {
529  eveIds.insert(sdp.trackID);
530  } //end sdps
531  } //End for hits
532  return eveIds;
533  }
534 
535  //----------------------------------------------------------------
537  std::vector<recob::OpHit> const& opHits) const
538  { /*NEW*/ /*COMPLETE*/
539  std::set<int> eveIds;
540  for (auto const& opHit : opHits) {
541  const std::vector<sim::TrackSDP> sdps = this->OpHitToEveTrackSDPs(opHit);
542  for (auto const& sdp : sdps) {
543  eveIds.insert(sdp.trackID);
544  } //end sdps
545  } //End for hits
546  return eveIds;
547  }
548 
549  //----------------------------------------------------------------
551  std::vector<art::Ptr<recob::OpHit>> const& opHits) const
552  {
553  std::set<int> tids;
554  for (auto const& opHit : opHits) {
555  for (auto const& sdp : this->OpHitToTrackSDPs(opHit)) {
556  tids.insert(sdp.trackID);
557  } //End for TrackSDPs
558  } //End for hits
559  return tids;
560  }
561 
562  //----------------------------------------------------------------
564  std::vector<recob::OpHit> const& opHits) const
565  { /*NEW*/ /*COMPLETE*/
566  std::set<int> tids;
567  for (auto const& opHit : opHits) {
568  for (auto const& sdp : this->OpHitToTrackSDPs(opHit)) {
569  tids.insert(sdp.trackID);
570  } //End for TrackSDPs
571  } //End for hits
572  return tids;
573  }
574 
575  //----------------------------------------------------------------
577  std::set<int> const& tkIds,
578  std::vector<art::Ptr<recob::OpHit>> const& opHits)
579  {
580  // get the list of EveIDs that correspond to the opHits in this collection
581  // if the EveID shows up in the input list of tkIds, then it counts
582  float total = 1. * opHits.size();
583  ;
584  float desired = 0.;
585  for (size_t h = 0; h < opHits.size(); ++h) {
586  art::Ptr<recob::OpHit> opHit = opHits[h];
587  std::vector<sim::TrackSDP> opHitTrackSDPs = this->OpHitToTrackSDPs(opHit);
588  // don't double count if this opHit has more than one of the
589  // desired track IDs associated with it
590  for (size_t e = 0; e < opHitTrackSDPs.size(); ++e) {
591  if (tkIds.find(opHitTrackSDPs[e].trackID) != tkIds.end()) {
592  desired += 1.;
593  break;
594  }
595  }
596  } // end loop over opHits
597  double purity = 0.;
598  if (total > 0) purity = desired / total;
599  return purity;
600  }
601 
602  //----------------------------------------------------------------
604  std::set<int> const& tkIds,
605  std::vector<art::Ptr<recob::OpHit>> const& opHits)
606  {
607  // get the list of EveIDs that correspond to the opHits in this collection
608  // if the EveID shows up in the input list of tkIds, then it counts
609  float total = 0;
610  float desired = 0.;
611  // don't have to check the view in the opHits collection because
612  // those are assumed to be from the object we are testing and will
613  // the correct view by definition then.
614  for (size_t h = 0; h < opHits.size(); ++h) {
615  art::Ptr<recob::OpHit> opHit = opHits[h];
616  std::vector<sim::TrackSDP> opHitTrackIDs = this->OpHitToTrackSDPs(opHit);
617  total += opHit->Area(); // sum up the charge in the cluster
618  // don't double count if this opHit has more than one of the
619  // desired track IDs associated with it
620  for (size_t e = 0; e < opHitTrackIDs.size(); ++e) {
621  if (tkIds.find(opHitTrackIDs[e].trackID) != tkIds.end()) {
622  desired += opHit->Area();
623  break;
624  }
625  }
626  } // end loop over opHits
627  double purity = 0.;
628  if (total > 0) purity = desired / total;
629  return purity;
630  }
631 
632  //----------------------------------------------------------------
634  std::set<int> const& tkIds,
635  std::vector<art::Ptr<recob::OpHit>> const& opHits,
636  std::vector<art::Ptr<recob::OpHit>> const& opHitsIn,
637  geo::View_t const& view)
638  {
639  throw cet::exception("PhotonBackTracker")
640  << "This function is not supported. OpHits do not have type View.\n";
641  }
642 
643  //----------------------------------------------------------------
645  std::set<int> const& tkIds,
646  std::vector<art::Ptr<recob::OpHit>> const& opHits,
647  std::vector<art::Ptr<recob::OpHit>> const& opHitsIn)
648  {
649  float desired = 0.;
650  float total = 0.;
651  for (size_t h = 0; h < opHits.size(); ++h) {
652  art::Ptr<recob::OpHit> opHit = opHits[h];
653  std::vector<sim::TrackSDP> opHitTrackSDPs = this->OpHitToTrackSDPs(opHit);
654  // also don't double count if this opHit has more than one of the
655  // desired track IDs associated with it
656  for (size_t e = 0; e < opHitTrackSDPs.size(); ++e) {
657  if (tkIds.find(opHitTrackSDPs[e].trackID) != tkIds.end() &&
658  opHitTrackSDPs[e].energyFrac >= fMinOpHitEnergyFraction) {
659  desired += 1.;
660  break;
661  }
662  }
663  } // end loop over opHits
664  // now figure out how many opHits in the whole collection are associated with this id
665  for (size_t h = 0; h < opHitsIn.size(); ++h) {
666  art::Ptr<recob::OpHit> opHit = opHitsIn[h];
667  std::vector<sim::TrackSDP> opHitTrackSDPs = this->OpHitToTrackSDPs(opHit);
668  for (size_t e = 0; e < opHitTrackSDPs.size(); ++e) {
669  // don't worry about opHits where the energy fraction for the chosen
670  // trackID is < 0.1
671  // also don't double count if this opHit has more than one of the
672  // desired track IDs associated with it
673  if (tkIds.find(opHitTrackSDPs[e].trackID) != tkIds.end() &&
674  opHitTrackSDPs[e].energyFrac >= fMinOpHitEnergyFraction) {
675  total += 1.;
676  break;
677  }
678  }
679  } // end loop over all opHits
680  double efficiency = 0.;
681  if (total > 0.) efficiency = desired / total;
682  return efficiency;
683  }
684 
685  //----------------------------------------------------------------
687  std::set<int> const& tkIds,
688  std::vector<art::Ptr<recob::OpHit>> const& opHits,
689  std::vector<art::Ptr<recob::OpHit>> const& opHitsIn,
690  geo::View_t const& view)
691  {
692  throw cet::exception("PhotonBackTracker")
693  << "This function is not supported. OpHits do not have type View.\n";
694  }
695 
696  //----------------------------------------------------------------
698  std::set<int> const& tkIds,
699  std::vector<art::Ptr<recob::OpHit>> const& opHits,
700  std::vector<art::Ptr<recob::OpHit>> const& opHitsIn)
701  {
702  float desired = 0.;
703  float total = 0.;
704 
705  // don't have to check the view in the opHits collection because
706  // those are assumed to be from the object we are testing and will
707  // the correct view by definition then.
708  for (size_t h = 0; h < opHits.size(); ++h) {
709 
710  art::Ptr<recob::OpHit> opHit = opHits[h];
711  std::vector<sim::TrackSDP> opHitTrackIDs = this->OpHitToTrackSDPs(opHit);
712 
713  // don't worry about opHits where the energy fraction for the chosen
714  // trackID is < 0.1
715  // also don't double count if this opHit has more than one of the
716  // desired track IDs associated with it
717  for (size_t e = 0; e < opHitTrackIDs.size(); ++e) {
718  if (tkIds.find(opHitTrackIDs[e].trackID) != tkIds.end() &&
719  opHitTrackIDs[e].energyFrac >= fMinOpHitEnergyFraction) {
720  desired += opHit->Area();
721  break;
722  }
723  }
724  } // end loop over opHits
725  for (size_t h = 0; h < opHitsIn.size(); ++h) {
726  art::Ptr<recob::OpHit> opHit = opHitsIn[h];
727  // check that we are looking at the appropriate view here
728  // in the case of 3D objects we take all opHits
729  //if(opHit->View() != view && view != geo::k3D ) continue;
730  std::vector<sim::TrackSDP> opHitTrackIDs = this->OpHitToTrackSDPs(opHit);
731  for (size_t e = 0; e < opHitTrackIDs.size(); ++e) {
732  // don't worry about opHits where the energy fraction for the chosen
733  // trackID is < 0.1
734  // also don't double count if this opHit has more than one of the
735  // desired track IDs associated with it
736  if (tkIds.find(opHitTrackIDs[e].trackID) != tkIds.end() &&
737  opHitTrackIDs[e].energyFrac >= fMinOpHitEnergyFraction) {
738  total += opHit->Area();
739  break;
740  }
741  }
742  } // end loop over all opHits
743  double efficiency = 0.;
744  if (total > 0.) efficiency = desired / total;
745  return efficiency;
746  }
747  //--------------------------------------------------
748  const std::vector<art::Ptr<recob::OpHit>> PhotonBackTracker::OpFlashToOpHits_Ps(
749  art::Ptr<recob::OpFlash>& flash_P) const
750  // const std::vector<art::Ptr<recob::OpHit>> PhotonBackTracker::OpFlashToOpHits_Ps(art::Ptr<recob::OpFlash>& flash_P, Evt const& evt) const
751  { //There is not "non-pointer" version of this because the art::Ptr is needed to look up the assn. One could loop the Ptrs and dereference them, but I will not encourage the behavior by building the tool to do it.
752  //
753  std::vector<art::Ptr<recob::OpHit>> const& hits_Ps = priv_OpFlashToOpHits.at(flash_P);
754  return hits_Ps;
755  }
756 
757  //--------------------------------------------------
758  const std::vector<double> PhotonBackTracker::OpFlashToXYZ(art::Ptr<recob::OpFlash>& flash_P) const
759  {
760  const std::vector<art::Ptr<recob::OpHit>> opHits_Ps = this->OpFlashToOpHits_Ps(flash_P);
761  const std::vector<double> retVec = this->OpHitsToXYZ(opHits_Ps);
762  //const std::vector<double> retVec(0.0,3);
763  return retVec;
764  }
765 
766  //--------------------------------------------------
768  {
769  std::vector<art::Ptr<recob::OpHit>> opHits_Ps = this->OpFlashToOpHits_Ps(flash_P);
770  std::set<int> ids;
771  for (auto& opHit_P : opHits_Ps) {
772  for (const int& id : this->OpHitToTrackIds(opHit_P)) {
773  ids.insert(id);
774  } // end for ids
775  } // end for opHits
776  // std::set<int> ids;
777  return ids;
778  } // end OpFlashToTrackIds
779 
780  //----------------------------------------------------- /*NEW*/
781  //----------------------------------------------------- /*NEW*/
782  //----------------------------------------------------- /*NEW*/
783  //----------------------------------------------------- /*NEW*/
784  //----------------------------------------------------- /*NEW*/
785  //std::vector<sim::TrackSDP> OpFlashToTrackSDPs(art::Ptr<recob::OpFlash> flash_P);
786  //----------------------------------------------------- /*NEW*/
787  //std::vector<sim::TrackSDP> OpFlashToTrackSDPs(recob::OpFlash flash);
788  //----------------------------------------------------- /*NEW*/
789  //std::vector<sim::TrackSDP> OpFlashToEveTrackSDPs(recob::OpFlash flash);
790  //----------------------------------------------------- /*NEW*/
791  //std::vector<sim::TrackSDP> OpFlashToEveTrackSDPs(art::Ptr<recob::OpFlash> flash_P);
792  //----------------------------------------------------- /*NEW*/
793  //std::vector<sim::SDP*> OpFlashToSimSDPs_Ps(recob::OpFlash flash);
794  //----------------------------------------------------- /*NEW*/
795  //std::vector<sim::SDP*> OpFlashToSimSDPs_Ps(art::Ptr<recob::OpFlash> flash_P);
796 
797  //----------------------------------------------------------------------
798 } // namespace
Float_t x
Definition: compare.C:6
const art::Ptr< sim::OpDetBacktrackerRecord > FindOpDetBTR(int const &opDetNum) const
const std::unordered_set< const sim::SDP * > OpHitToEveSimSDPs_Ps(recob::OpHit const &opHit)
std::map< art::Ptr< recob::OpFlash >, std::vector< art::Ptr< recob::OpHit > > > priv_OpFlashToOpHits
const std::vector< art::Ptr< recob::OpHit > > TrackIdToOpHits_Ps(int const &tkId, std::vector< art::Ptr< recob::OpHit >> const &hitsIn)
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
Float_t y
Definition: compare.C:6
Double_t z
Definition: plot.C:276
std::vector< double > SimSDPsToXYZ(std::vector< sim::SDP > const &sdps)
constexpr auto abs(T v)
Returns the absolute value of the argument.
double PeakTime() const
Definition: OpHit.h:94
STL namespace.
const std::vector< const sim::SDP * > TrackIdToSimSDPs_Ps(int const &id)
std::string fG4ModuleLabel
label for geant4 module
std::vector< double > OpHitToXYZ(art::Ptr< recob::OpHit > const &hit)
const std::vector< sim::TrackSDP > OpHitToEveTrackSDPs(art::Ptr< recob::OpHit > const &opHit_P) const
unsigned int OpDetFromOpChannel(int opChannel) const
Convert unique channel to detector number.
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:289
Access the description of detector geometry.
const std::set< int > OpFlashToTrackIds(art::Ptr< recob::OpFlash > &flash_P) const
const std::set< int > GetSetOfEveIds() const
const std::vector< double > OpHitsToXYZ(std::vector< art::Ptr< recob::OpHit >> const &opHits_Ps) const
double Width() const
Definition: OpHit.h:110
const std::vector< std::vector< art::Ptr< recob::OpHit > > > TrackIdsToOpHits_Ps(std::vector< int > const &tkIds, std::vector< art::Ptr< recob::OpHit >> const &hitsIn)
int trackID
Geant4 supplied trackID.
const cheat::ParticleInventory * fPartInv
std::vector< art::Ptr< sim::OpDetBacktrackerRecord > > priv_OpDetBTRs
static const int NoParticleId
Definition: sim.h:21
const geo::GeometryCore * fGeom
float energyFrac
fraction of OpHit energy from the particle with this trackID
double timePDclock_t
Type for iTimePDclock tick used in the interface.
double energy
Definition: plottest35.C:25
std::set< int > GetSetOfTrackIds() const
back track the reconstruction to the simulation
std::set< int > GetSetOfEveIds() const
Description of geometry of one entire detector.
Definition: GeometryCore.h:119
const std::vector< int > OpHitToEveTrackIds(recob::OpHit const &opHit)
Ionization photons from a Geant4 track.
const art::InputTag fOpFlashLabel
double weight
Definition: plottest35.C:25
std::vector< sim::TrackSDP > OpHitToTrackSDPs(art::Ptr< recob::OpHit > const &hit)
decltype(auto) get(T &&obj)
ADL-aware version of std::to_string.
Definition: StdUtils.h:120
PhotonBackTracker(fhicl::ParameterSet const &pset, art::ActivityRegistry &reg)
code to link reconstructed objects back to the MC truth information
Definition: BackTracker.cc:22
const std::set< int > GetSetOfTrackIds() const
const std::vector< art::InputTag > fG4ModuleLabels
geo::GeometryCore const * geom
const std::vector< int > OpHitToTrackIds(recob::OpHit const &opHit) const
const std::vector< const sim::SDP * > OpHitsToSimSDPs_Ps(std::vector< art::Ptr< recob::OpHit >> const &opHits_Ps) const
Float_t sc
Definition: plot.C:23
double OpHitCollectionEfficiency(std::set< int > trackIDs, std::vector< art::Ptr< recob::OpHit >> const &hits, std::vector< art::Ptr< recob::OpHit >> const &allhits)
const double OpHitLightCollectionEfficiency(std::set< int > const &tkIds, std::vector< art::Ptr< recob::OpHit >> const &opHits, std::vector< art::Ptr< recob::OpHit >> const &opHitsIn)
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
Header for the ParticleInvenotry Service Provider.
const std::vector< const sim::SDP * > OpHitToSimSDPs_Ps(recob::OpHit const &opHit) const
double OpHitCollectionPurity(std::set< int > trackIDs, std::vector< art::Ptr< recob::OpHit >> const &hits)
Definition: MVAAlg.h:12
double fMinOpHitEnergyFraction
minimum fraction of energy a track id has to
const art::InputTag fOpHitLabel
double Area() const
Definition: OpHit.h:114
std::vector< sim::SDP > TrackIDsAndEnergies(timePDclock_t startTimePDclock, timePDclock_t endTimePDclock) const
Return all the recorded energy deposition within a time interval.
std::vector< art::Ptr< sim::OpDetBacktrackerRecord > > const & OpDetBTRs()
const std::vector< double > OpFlashToXYZ(art::Ptr< recob::OpFlash > &flash_P) const
float energy
energy from the particle with this trackID [MeV]
Float_t e
Definition: plot.C:35
Float_t w
Definition: plot.C:20
int OpChannel() const
Definition: OpHit.h:86
Tools and modules for checking out the basics of the Monte Carlo.
const sim::ParticleList & ParticleList() const
const std::vector< sim::TrackSDP > OpDetToTrackSDPs(int const &OpDetNum, double const &opHit_start_time, double const &opHit_end_time) const
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
const std::vector< art::Ptr< recob::OpHit > > OpFlashToOpHits_Ps(art::Ptr< recob::OpFlash > &flash_P) const
const double OpHitLightCollectionPurity(std::set< int > const &tkIds, std::vector< art::Ptr< recob::OpHit >> const &opHits)