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