13 #include "art/Framework/Principal/Event.h"
14 #include "art/Framework/Principal/View.h"
15 #include "messagefacility/MessageLogger/MessageLogger.h"
24 #include "nug4/ParticleNavigation/EmEveIdCalculator.h"
25 #include "nusimdata/SimulationBase/MCParticle.h"
34 art::ActivityRegistry& reg)
49 fG4ModuleLabel = pset.get<std::string>(
"G4ModuleLabel",
"largeant");
51 fDelay = pset.get<
double > (
"Delay");
59 if(evt.isRealData())
return;
62 art::Handle<std::vector<simb::MCParticle>> pHandle;
68 if(pHandle.failedToGet()){
69 mf::LogWarning(
"PhotonBackTracker") <<
"failed to get handle to simb::MCParticle from "
84 for(
size_t p = 0;
p < pHandle->size(); ++
p){
86 simb::MCParticle *part =
new simb::MCParticle(pHandle->at(
p));
91 art::Ptr<simb::MCTruth> mct = fo.at(
p);
103 catch(cet::exception &ex){
104 mf::LogWarning(
"PhotonBackTracker") <<
"unable to find MCTruth from ParticleList "
106 <<
"any attempt to get the MCTruth objects from "
107 <<
"the photon backtracker will fail\n"
108 <<
"message from caught exception:\n" << ex;
124 art::Handle< std::vector< sim::OpDetBacktrackerRecord> > cPBTRHandle;
127 if(cPBTRHandle.failedToGet()){
128 auto failMode = cPBTRHandle.whyFailed();
129 if(failMode->categoryCode() != art::errors::ProductNotFound)
throw;
131 std::cout<<
"FAILED BECAUSE "<<(*failMode)<<
"\n";
133 mf::LogWarning(
"PhotonBackTracker")<<
"Failed to get BackTrackerRecords from this event. All calls to the PhotonBackTracker will fail.\n"
134 <<
"This message will be generated only once per lar invokation. If this is event one, be aware the PhotonBackTracker may not work on any events from this file.\n"
135 <<
"Please change the log level to debug if you need more information for each event.\n"
136 <<
"Failed with :"<<(*failMode)<<
"\n";
137 mf::LogDebug(
"PhotonBackTracker")<<
"Failed to get BackTrackerRecords from this event.\n";
139 mf::LogDebug(
"PhotonBackTracker")<<
"Failed to get BackTrackerRecords from this event.\n";
149 fParticleList.AdoptEveIdCalculator(
new sim::EmEveIdCalculator);
153 <<
" tracks. The particles are:\n"
155 <<
"\n the MCTruth information is\n";
157 MF_LOG_DEBUG(
"PhotonBackTracker") << *(
fMCTruthList.at(mc).get());
168 throw cet::exception(
"PhotonBackTracker1") <<
"PhotonBackTracker methods called on a file without OpDetPhotonBacktrackerRecords. Backtracked information is not available.";
176 sim::ParticleList::const_iterator part_it =
fParticleList.find(
id);
179 mf::LogWarning(
"PhotonBackTracker") <<
"can't find particle with track id "
180 <<
id <<
" in sim::ParticleList"
181 <<
" returning null pointer";
185 return part_it->second;
206 throw cet::exception(
"PhotonBackTracker") <<
"attempting to find MCTruth index for "
207 <<
"out of range value: " << mct
217 std::vector<sim::SDP> sdps;
225 for(
auto mapitr = pdTimeSDPmap.begin(); mapitr != pdTimeSDPmap.end(); mapitr++){
228 const std::vector<sim::SDP>& sdpvec = (*mapitr).second;
229 for(
size_t iv = 0; iv < sdpvec.size(); ++iv){
230 if(
abs(sdpvec[iv].trackID) == id) sdps.push_back(sdpvec[iv]);
250 std::vector<const simb::MCParticle*> ret;
253 for (
const sim::ParticleList::value_type& TrackIDpair:
fParticleList) {
255 ret.push_back(TrackIDpair.second);
265 std::vector<sim::TrackSDP> trackSDPs;
266 const double pTime = opHit->PeakTime();
267 const double pWidth= opHit->Width();
268 const double start = (pTime-pWidth)*1000-
fDelay;
269 const double end = (pTime+pWidth)*1000-
fDelay;
278 std::vector<int>
const& tkIDs)
286 std::vector<std::pair<int, art::Ptr<recob::OpHit>>> opHitList;
287 std::vector<sim::TrackSDP> tids;
288 for(
auto itr = allOpHits.begin(); itr != allOpHits.end(); ++itr) {
290 art::Ptr<recob::OpHit>
const& opHit = *itr;
291 const double pTime = opHit->PeakTime(), pWidth= opHit->Width();
292 const double start = (pTime-pWidth)*1000.0-
fDelay,
end = (pTime+pWidth)*1000.0-
fDelay;
294 for(
auto itid = tids.begin(); itid != tids.end(); ++itid) {
295 for(
auto itkid = tkIDs.begin(); itkid != tkIDs.end(); ++itkid) {
296 if(itid->trackID == *itkid) {
298 opHitList.push_back(std::make_pair(*itkid, opHit));
305 std::vector<std::vector<art::Ptr<recob::OpHit>>> truOpHits;
307 std::vector<art::Ptr<recob::OpHit>> tmpOpHits;
308 for(
auto itkid = tkIDs.begin(); itkid != tkIDs.end(); ++itkid) {
310 for(
auto itr = opHitList.begin(); itr != opHitList.end(); ++itr) {
311 if(*itkid == (*itr).first) tmpOpHits.push_back((*itr).second);
313 truOpHits.push_back(tmpOpHits);
328 std::map<int, float> eveIDtoEfrac;
331 for(
size_t t = 0; t < trackSDPs.size(); ++t){
332 eveIDtoEfrac[
fParticleList.EveId( trackSDPs[t].trackID )] += trackSDPs[t].energy;
333 totalE += trackSDPs[t].energy;
337 std::vector<sim::TrackSDP> eveSDPs;
338 eveSDPs.reserve(eveIDtoEfrac.size());
339 for(
auto itr = eveIDtoEfrac.begin(); itr != eveIDtoEfrac.end(); itr++){
343 temp.
energy = (*itr).second;
344 eveSDPs.push_back(std::move(temp));
351 mf::LogWarning(
"PhotonBackTracker") <<
"PhotonBackTracker::OpHitToEveID is being replaced with PhotonBackTracker::OpHitToEveSDPs. Please \n update your code accordingly.\n ";
360 std::set<int> eveIDs;
362 sim::ParticleList::const_iterator plitr =
fParticleList.begin();
366 if( eveIDs.find(eveID) == eveIDs.end() ) eveIDs.insert(eveID);
378 std::set<int> trackIDs;
380 trackIDs.insert(pl.first);
389 std::set<int> eveIDs;
391 std::vector< art::Ptr<recob::OpHit> >::const_iterator itr = opHits.begin();
392 while(itr != opHits.end() ){
395 const std::vector<sim::TrackSDP> sdps =
OpHitToEveID(*itr);
398 for(
size_t i = 0; i < sdps.size(); ++i) eveIDs.insert(sdps[i].trackID);
410 std::set<int> trackIDs;
412 std::vector< art::Ptr<recob::OpHit> >::const_iterator itr = opHits.begin();
413 while(itr != opHits.end() ){
415 std::vector<sim::TrackSDP> trackSDPs;
418 const double pTime = (*itr)->PeakTime();
419 const double pWidth= (*itr)->Width();
420 const double start = (pTime-pWidth)*1000.0-
fDelay;
421 const double end = (pTime+pWidth)*1000.0-
fDelay;
428 for(
size_t i = 0; i < trackSDPs.size(); ++i) {
429 trackIDs.insert(trackSDPs[i].trackID);
440 std::vector< art::Ptr<recob::OpHit> >
const& opHits)
445 float total = 1.*opHits.size();;
447 for(
size_t h = 0;
h < opHits.size(); ++
h){
448 art::Ptr<recob::OpHit> opHit = opHits[
h];
452 for(
size_t e = 0;
e < opHitTrackSDPs.size(); ++
e){
453 if(trackIds.find(opHitTrackSDPs[
e].trackID) != trackIds.end()){
460 if(total > 0) purity = desired/total;
466 std::vector< art::Ptr<recob::OpHit> >
const& opHits)
476 for(
size_t h = 0;
h < opHits.size(); ++
h){
477 art::Ptr<recob::OpHit> opHit = opHits[
h];
479 total+=opHit->Area();
482 for(
size_t e = 0;
e < opHitTrackIDs.size(); ++
e){
483 if(trackIDs.find(opHitTrackIDs[
e].trackID) != trackIDs.end()){
484 desired += opHit->Area();
490 if(total > 0) purity = desired/total;
497 std::vector< art::Ptr<recob::OpHit> >
const& opHits,
498 std::vector< art::Ptr<recob::OpHit> >
const& allOpHits,
501 throw cet::exception(
"PhotonBackTracker")<<
"This function is not supported. OpHits do not have type View.\n";
509 for(
size_t h = 0;
h < opHits.size(); ++
h){
510 art::Ptr<recob::OpHit> opHit = opHits[
h];
514 for(
size_t e = 0;
e < opHitTrackSDP.size(); ++
e){
515 if(trackIDs.find(opHitTrackSDPs[
e].trackID) != trackIDs.end() &&
523 for(
size_t h = 0;
h < allOpHits.size(); ++
h){
524 art::Ptr<recob::OpHit> opHit = allOpHits[
h];
526 for(
size_t e = 0;
e < opHitTrackSDPs.size(); ++
e){
531 if(trackIDs.find(opHitTrackSDPs[
e].trackID) != trackIDs.end() &&
538 double efficiency = 0.;
539 if(total > 0.) efficiency = desired/total;
545 std::vector< art::Ptr<recob::OpHit> >
const& opHits,
546 std::vector< art::Ptr<recob::OpHit> >
const& allOpHits,
549 throw cet::exception(
"PhotonBackTracker")<<
"This function is not supported. OpHits do not have type View.\n";
552 std::vector< art::Ptr<recob::OpHit> >
const& opHits,
553 std::vector< art::Ptr<recob::OpHit> >
const& allOpHits)
564 for(
size_t h = 0;
h < opHits.size(); ++
h){
566 art::Ptr<recob::OpHit> opHit = opHits[
h];
573 for(
size_t e = 0;
e < opHitTrackIDs.size(); ++
e){
574 if(trackIDs.find(opHitTrackIDs[
e].trackID) != trackIDs.end() &&
576 desired += opHit->Area();
583 for(
size_t h = 0;
h < allOpHits.size(); ++
h){
585 art::Ptr<recob::OpHit> opHit = allOpHits[
h];
593 for(
size_t e = 0;
e < opHitTrackIDs.size(); ++
e){
598 if(trackIDs.find(opHitTrackIDs[
e].trackID) != trackIDs.end() &&
600 total += opHit->Area();
607 double efficiency = 0.;
608 if(total > 0.) efficiency = desired/total;
619 art::Ptr< sim::OpDetBacktrackerRecord > opDet;
628 throw cet::exception(
"PhotonBackTracker2") <<
"No sim::OpDetBacktrackerRecord corresponding "
629 <<
"to opDetNum: " << opDetNum <<
"\n";
638 const double opHit_start_time,
639 const double opHit_end_time)
656 std::vector<sim::SDP> simSDPs = schannel->TrackIDsAndEnergies(opHit_start_time, opHit_end_time);
660 for(
size_t e = 0;
e < simSDPs.size(); ++
e)
661 totalE += simSDPs[
e].energy;
665 if(totalE < 1.
e-5) totalE = 1.;
669 for(
size_t e = 0;
e < simSDPs.size(); ++
e){
676 info.
energy = simSDPs[
e].energy;
678 trackSDPs.push_back(info);
682 catch(cet::exception
e){
683 mf::LogWarning(
"PhotonBackTracker") <<
"caught exception \n"
692 std::vector<sim::SDP>& sdps)
const
698 double fPeakTime = opHit.
PeakTime();
699 double fWidth = opHit.
Width();
711 std::vector<double> xyz(3, -999.);
720 for(
auto const& sdp : sdps) {
722 double weight = sdp.numPhotons;
734 throw cet::exception(
"PhotonBackTracker") <<
"No sim::SDPs providing non-zero number of photons"
735 <<
" can't determine originating location from truth\n";
748 std::vector<sim::SDP> sdps;
756 DEFINE_ART_SERVICE(PhotonBackTracker)
const simb::MCParticle * TrackIDToParticle(int const &id) const
const void shouldThisFail() const
process_name opflash particleana ie ie ie z
std::vector< const simb::MCParticle * > MCTruthToParticles(art::Ptr< simb::MCTruth > const &mct) const
std::vector< double > OpHitToXYZ(art::Ptr< recob::OpHit > const &hit)
std::map< int, int > fTrackIDToMCTruthIndex
map of track ids to MCTruthList entry
process_name opflash particleana ie x
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
std::vector< sim::SDP > TrackIDToSimSDP(int const &id) const
std::vector< double > SimSDPsToXYZ(std::vector< sim::SDP > const &sdps)
double OpHitCollectionPurity(std::set< int > trackIDs, std::vector< art::Ptr< recob::OpHit > > const &hits)
const art::Ptr< simb::MCTruth > & ParticleToMCTruth(const simb::MCParticle *p) const
std::string fG4ModuleLabel
label for geant4 module
unsigned int OpDetFromOpChannel(int opChannel) const
Convert unique channel to detector number.
double OpHitChargeCollectionEfficiency(std::set< int > trackIDs, std::vector< art::Ptr< recob::OpHit > > const &hits, std::vector< art::Ptr< recob::OpHit > > const &allhits)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Access the description of detector geometry.
then echo fcl sbnd_project sbnd_project sbnd_project sbnd_project production production end_time
void OpHitToSDPs(recob::OpHit const &hit, std::vector< sim::SDP > &sdps) const
process_name opflash particleana ie ie y
void reconfigure(fhicl::ParameterSet const &pset)
int trackID
Geant4 supplied trackID.
std::vector< sim::TrackSDP > OpHitToEveSDPs(art::Ptr< recob::OpHit > const &hit)
static const int NoParticleId
void ChannelToTrackSDPs(std::vector< sim::TrackSDP > &trackSDPs, int channel, const double hit_start_time, const double hit_end_time)
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
double OpHitCollectionEfficiency(std::set< int > trackIDs, std::vector< art::Ptr< recob::OpHit > > const &hits, std::vector< art::Ptr< recob::OpHit > > const &allhits)
back track the reconstruction to the simulation
const simb::MCParticle * TrackIDToMotherParticle(int const &id) const
void Rebuild(const art::Event &evt)
std::set< int > GetSetOfTrackIDs()
Ionization photons from a Geant4 track.
std::vector< sim::TrackSDP > OpHitToTrackSDPs(art::Ptr< recob::OpHit > const &hit)
std::vector< sim::TrackSDP > OpHitToEveID(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 ®)
const art::Ptr< sim::OpDetBacktrackerRecord > FindOpDetBacktrackerRecord(int channel) const
geo::GeometryCore const * geom
double fMinOpHitEnergyFraction
minimum fraction of energy a track id has to
float energy
energy from the particle with this trackID [MeV]
std::vector< art::Ptr< sim::OpDetBacktrackerRecord > > cOpDetBacktrackerRecords
all the OpDetBacktrackerRecords for the event
std::vector< art::Ptr< simb::MCTruth > > fMCTruthList
all the MCTruths for the event
double OpHitChargeCollectionPurity(std::set< int > trackIDs, std::vector< art::Ptr< recob::OpHit > > const &hits)
Tools and modules for checking out the basics of the Monte Carlo.
const std::vector< std::vector< art::Ptr< recob::OpHit > > > TrackIDsToOpHits(std::vector< art::Ptr< recob::OpHit >> const &allhits, std::vector< int > const &tkIDs)
sim::ParticleList fParticleList
ParticleList to map track ID to sim::Particle.
art framework interface to geometry description
BEGIN_PROLOG could also be cout
const art::Ptr< simb::MCTruth > & TrackIDToMCTruth(int const &id) const
std::set< int > GetSetOfEveIDs()