#include "TrackTruthInfo.hxx" #include #include #include #include #include #include #include #include #include "retrieveHitTruthInfo.hxx" namespace TrackTruthInfo { std::map GetG4Trajectories(const COMET::IHitSelection &hits) { std::map counts; // then loop over everything and log the trajectory ids. for (COMET::IHitSelection::const_iterator hit = hits.begin(); hit != hits.end(); hit++) { std::vector contributors = HitTruthInfo::GetHitTruthInfo(*hit); for (std::vector::const_iterator g4Hit = contributors.begin(); g4Hit != contributors.end(); g4Hit++) { COMET::IG4HitSegment* g4HitCast = dynamic_cast(*g4Hit); for (unsigned int i = 0; i < g4HitCast->GetContributors().size(); i++) { int id = g4HitCast->GetContributors()[i]; // a std::map initializes any unused elements to zero counts[id]++; } } } return counts; } std::map GetG4TrajectoryFractions(const COMET::IHandle track) { COMET::IHandle hits = track->GetHits(); if (!hits) { COMETWarn("TrackTruthInfo::GetG4TrajectoryID : Track has no hits!"); return std::map(); } std::map counts = GetG4Trajectories(*hits); int total = 0; for (std::map::iterator t = counts.begin(); t != counts.end(); t++) total += t->second; std::map fractions; for (std::map::iterator t = counts.begin(); t != counts.end(); t++) fractions[t->first] = ((double) t->second)/((double) total); return fractions; } int GetG4TrajIDHits(const COMET::IHitSelection &hits) { std::map counts = GetG4Trajectories(hits); int maxID = 0; int maxCount = 0; if (counts.empty()) { COMETWarn("TrackTruthInfo::GetG4TrajIDHits : None of the hits have associated MC info."); return 0; } for (std::map::iterator tr = counts.begin(); tr != counts.end(); tr++) { if (tr->second > maxCount) { maxCount = tr->second; maxID = tr->first; } } return maxID; } int GetG4TrajectoryID(const COMET::IHandle track) { COMET::IHandle hits = track->GetHits(); if (!hits) { COMETWarn("TrackTruthInfo::GetG4TrajectoryID : Track has no hits!"); return 0; } return GetG4TrajIDHits(*hits); } COMET::IHandle GetG4TrajHits(const COMET::IHitSelection &hits) { int G4Id = GetG4TrajIDHits(hits); if (!G4Id){ return COMET::IHandle(); } const COMET::ICOMETEvent& event = *(COMET::IEventFolder::GetCurrentEvent()); COMET::IHandle trajectories = event.Get("truth/G4Trajectories"); if (!trajectories) return COMET::IHandle(NULL); return trajectories->GetTrajectory(G4Id); } COMET::IHandle GetG4Trajectory(const COMET::IHandle track) { int G4Id = GetG4TrajectoryID(track); if (!G4Id){ return COMET::IHandle(); } const COMET::ICOMETEvent& event = *(COMET::IEventFolder::GetCurrentEvent()); COMET::IHandle trajectories = event.Get("truth/G4Trajectories"); if (!trajectories) return COMET::IHandle(NULL); return trajectories->GetTrajectory(G4Id); } COMET::IHandle GetG4Trajectory(const COMET::IHandle track, double &complete, double &clean) { int G4Id = GetG4TrajectoryID(track, complete, clean); if (!G4Id){ return COMET::IHandle(); } const COMET::ICOMETEvent& event = *(COMET::IEventFolder::GetCurrentEvent()); COMET::IHandle trajectories = event.Get("truth/G4Trajectories"); if (!trajectories) return COMET::IHandle(NULL); return trajectories->GetTrajectory(G4Id); } bool HitMatchesTrajectory(COMET::IHandle hit, int g4id) { std::vector contributors = HitTruthInfo::GetHitTruthInfo(hit); for (std::vector::iterator g4Hit = contributors.begin(); g4Hit != contributors.end(); g4Hit++) { COMET::IG4HitSegment* g4HitCast = dynamic_cast(*g4Hit); for (unsigned int i = 0; i < g4HitCast->GetContributors().size(); i++) if (g4HitCast->GetContributors()[i] == g4id) return true; } return false; } COMET::IHandle GetTrueTrackHits(int g4id, COMET::IHandle universe) { COMET::IHandle trackHits(new COMET::IHitSelection()); for (COMET::IHitSelection::iterator hit = universe->begin(); hit != universe->end(); hit++) { if (HitMatchesTrajectory(*hit, g4id)) trackHits->push_back(*hit); } return trackHits; } //************************************************* std::map GetG4Trajectories(COMET::IHandle hit) { std::map counts; // then loop over everything and log the trajectory ids. std::vector contributors = HitTruthInfo::GetHitTruthInfo(hit); for (std::vector::const_iterator g4Hit = contributors.begin(); g4Hit != contributors.end(); g4Hit++) { COMET::IG4HitSegment* g4HitCast = dynamic_cast(*g4Hit); for (unsigned int i = 0; i < g4HitCast->GetContributors().size(); i++) { int id = g4HitCast->GetContributors()[i]; // a std::map initializes any unused elements to zero counts[id]++; } } return counts; } //************************************************* int GetG4TrajIDHits(const COMET::IHitSelection &hits, double &complete, double &clean, std::string views) { complete = -0xABCDEF; clean = -0xABCDEF; int TotalFoundPadsBars = 0; unsigned int DetectorUsed = 0; std::map recoCount; const COMET::ICOMETEvent& event = *(COMET::IEventFolder::GetCurrentEvent()); // Loop over everything and log the trajectory ids and the number of pads/bars for each id for (COMET::IHitSelection::const_iterator hit = hits.begin(); hit != hits.end(); hit++) { // Check if it is a IComboHit and expand COMET::IHandle combohit(*hit); COMET::IHandle recohit(*hit); if (combohit) { TotalFoundPadsBars += combohit->GetHits().size(); for (COMET::IHitSelection::const_iterator hit2 = combohit->GetHits().begin(); hit2 != combohit->GetHits().end(); hit2++) { // use a recursive call to get the constituents of the combo hit std::map tmpcount; tmpcount = GetG4Trajectories(*hit2); for (std::map::iterator it = tmpcount.begin(); it != tmpcount.end(); it++) recoCount[it->first]++; // Just count the number of pads/bars, not the number of contributions DetectorUsed |= HitToDetectorId(*hit2); } } // If not a IComboHit, check if it's a IReconHit else if (recohit){ TotalFoundPadsBars += recohit->GetContributorCount(); for ( int i=0; i < recohit->GetContributorCount(); i++){ COMET::IHandle hit3 = recohit->GetContributor(i); std::map tmpcount; tmpcount = GetG4Trajectories(hit3); for (std::map::iterator it = tmpcount.begin(); it != tmpcount.end(); it++) recoCount[it->first]++; // Just count the number of pads/bars, not the number of contributions DetectorUsed |= HitToDetectorId(hit3); } } else{ COMET::IHandle handleHit(*hit); TotalFoundPadsBars++; std::map tmpcount = GetG4Trajectories(handleHit); for (std::map::iterator it = tmpcount.begin(); it != tmpcount.end(); it++) recoCount[it->first]++; // Just count the number of pads/bars, not the number of contributions DetectorUsed |= HitToDetectorId(*hit); } // If not a IComboHit, just get the constituents } int maxID = 0; int maxCount = 0; if (recoCount.empty()) { COMETWarn("TrackTruthInfo::GetG4TrajIDHits : None of the hits have associated MC info."); return 0; } for (std::map::iterator tr = recoCount.begin(); tr != recoCount.end(); tr++) { if (tr->second > maxCount) { maxCount = tr->second; maxID = tr->first; } } if ( ! DetectorUsed) // Don't know where the hits are from, exit return maxID; // Cleanliness clean = (double)maxCount / (double)TotalFoundPadsBars; // Count the number of pads/bars from this true particle int TotalTruePadsBars = 0; COMET::IHandle hitV = event.Get("hits"); for(COMET::IDataVector::iterator hiter = hitV->begin(); hiter != hitV->end(); ++hiter){ COMET::IHitSelection* hitList = dynamic_cast(*hiter); for (COMET::IHitSelection::const_iterator hit = hitList->begin(); hit != hitList->end(); hit++) { if ( ! (DetectorUsed & HitToDetectorId(*hit)) ) continue; COMET::IHandle thit = *hit; if ( (views.find_first_of('3') != std::string::npos) || (views == "XY" && (thit->IsXHit() && thit->IsYHit() && !thit->IsZHit()) ) || (views == "YZ" && (!thit->IsXHit() && thit->IsYHit() && thit->IsZHit()) ) || (views == "XZ" && (thit->IsXHit() && !thit->IsYHit() && thit->IsZHit()) ) ) if ( HitMatchesTrajectory(*hit, maxID) ) TotalTruePadsBars++; } } // Completeness if (TotalTruePadsBars) complete = (double)maxCount / (double)TotalTruePadsBars; else COMETWarn("TrackTruthInfo::GetG4TrajIDHits : Missing true hits for efficiency calculation."); return maxID; } //************************************************* int GetG4TrajectoryID(const COMET::IHandle track, double &complete, double &clean) { COMET::IHandle hits = track->GetHits(); if (!hits) { COMETWarn("TrackTruthInfo::GetG4TrajectoryID : Track has no hits!"); return 0; } if (hits->size()<1) { COMETWarn("TrackTruthInfo::GetG4TrajectoryID : Track has no hits!"); return 0; } std::string views = "33"; COMET::IHandle rtrack = track; if(rtrack){ if ( rtrack->IsXTrack() && rtrack->IsYTrack() && !rtrack->IsZTrack() ) views = "XY"; else if ( rtrack->IsXTrack() && !rtrack->IsYTrack() && rtrack->IsZTrack() ) views = "XZ"; else if ( !rtrack->IsXTrack() && rtrack->IsYTrack() && rtrack->IsZTrack() ) views = "YZ"; } int G4Id = GetG4TrajIDHits(*hits, complete, clean, views); return G4Id; } //************************************************* int HitToDetectorId(COMET::IHandle hit) { COMET::IGeometryId geomId = hit->GetGeomId(); return GeomIdToDetectorId(geomId); } //************************************************* int GeomIdToDetectorId(COMET::IGeometryId geomId) { // Use things in ND namespace using COMET::IReconBase; namespace GeomId = COMET::GeomId; // Due to circular a dependency, we can't use oaGeomInfo. // We must do this by hand. //Start by doing all the detectors that are determined // uniquely by their subsystem ID : P0D, DsECal and SMRD int ssid = geomId.GetSubsystemId(); if (ssid == GeomId::Def::kCDC) return IReconBase::kCDC; if (ssid == GeomId::Def::kCTH) return IReconBase::kCTH; if (ssid == GeomId::Def::kECAL) return IReconBase::kECAL; if (ssid == GeomId::Def::kStrawTrk) return IReconBase::kStrawTrk; return 0; } //************************************************* int GetDetectorCrossedByG4Traj(COMET::IHandle g4traj) { return (GetDetectorCrossedByG4Traj(g4traj->GetTrackId())); } //************************************************* int GetDetectorCrossedByG4Traj(int g4id) { int DetectorCrossed = 0; const COMET::ICOMETEvent& event = *(COMET::IEventFolder::GetCurrentEvent()); COMET::IHandle hitV = event.Get("hits"); for(COMET::IDataVector::iterator hiter = hitV->begin(); hiter != hitV->end(); ++hiter){ COMET::IHitSelection* hitList = dynamic_cast(*hiter); for (COMET::IHitSelection::const_iterator hit = hitList->begin(); hit != hitList->end(); hit++) { if ( HitMatchesTrajectory(*hit, g4id)){ DetectorCrossed = DetectorCrossed | HitToDetectorId(*hit); } } } return DetectorCrossed; } //************************************************* COMET::IG4TrajectoryPoint GetCloserG4Point(COMET::IHandle traj, TVector3 *Position, double &dist){ std::vector points = traj->GetTrajectoryPoints(); double x0 = Position->X(); double y0 = Position->Y(); double z0 = Position->Z(); double dmin = DBL_MAX; int icloser = -1; for(unsigned int i = 0 ; i < points.size() ; i++ ) { double deltaz = (points[i].GetPosition().Z()-z0); double deltay = (points[i].GetPosition().Y()-y0); double deltax = (points[i].GetPosition().X()-x0); double distance = TMath::Sqrt(deltax*deltax+deltay*deltay+deltaz*deltaz); if( distance < dmin ) { dmin = distance; icloser = i; } } if( icloser >= 0 ) { dist = dmin; return points[icloser]; } else { COMETWarn("TrackTruthInfo::GetCloserG4Point : None of the true points are close to the hit."); return COMET::IG4TrajectoryPoint(); } } }