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