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