#ifndef TShowerTruthInfo_hxx_seen #define TShowerTruthInfo_hxx_seen #include #include #include #include #include #include #include #include namespace COMET { class IShowerTruthInfo; } ; /// This class provides three truth-matching algorithms for matching a /// reconstructed object or hit selection to a true trajectory. /// /// The three algorithms are: /// /// 1) Single trajectory matching. /// This matches an object to the individual true trajectories that /// contributed to it. This is functionally equivalent to the /// TrackTruthInfo method of matching. /// /// 2) Primary trajectory matching. /// This matches an object to the primary particle that produced the /// trajectories that contributed to the object. The primary particle /// is defined as either /// * a photon from a pi0 decay /// * an electron from a muon decay /// * the immediate product of a neutrino interaction. /// For particle guns, the primary particle is the particle gun particle /// itself. The completeness and cleanliness of the object is calculated /// from the primary particle and all of its daughters, not just the /// primary particle itself. /// /// 3) Recursive trajectory matching. /// This matches an object to the highest-level non-neutrino particle /// that enters the subdetectors used by the object and that has /// daughters that contribute to the object. As with the primary /// matching method, the completeness and cleanliness is calculated for /// the "top-level" particle and all of its daughters together, not just /// the top-level particle itself. /// /// By default, the results of all three algorithms are computed. The user can /// choose to disable certain calculations if they will not use the results. class COMET::IShowerTruthInfo { public: /// Struct returned for each trajectory we match against struct TruthInfo { /// The ID number of the matched trajectory. int ParticleID; /// The number of hits this trajectory is responsible for. For the /// recursive and primary algorithms, this includes the number of hits /// from descendants too. int NumHits; /// The completeness in terms of the number of hits. double Completeness_NumHits; /// The cleanliness in terms of the number of hits. The sum of /// cleanlinesses can exceed 1, as a hit may have contributions from /// several particles. For the recursive and primary matching methods, /// hits are not double counted if the contributing trajectories are /// related to the same top-level trajectory. double Cleanliness_NumHits; /// The amount of G4 energy deposit this trajectory (and descendants /// if appropriate) is responsible for. double G4Energy; /// The completeness in terms of the G4 energy of this trajectory. double Completeness_G4Energy; /// The cleanliness in terms of the G4 energy deposited. This measure /// does not have the same double-counting issue as the /// Cleanliness_NumHits measure. However, noise hits do not have any G4 /// hits associated with them, so we can only make an estimate as to /// how much G4 energy a noise hit is equivalent to. double Cleanliness_G4Energy; }; /// Define how to sort a vector of TruthInfo structs. enum SortOrder { /// Sort by descending number of hits matched to. If two trajectories /// match to the same number of hits, sort them by ascending ParticleID. kNumHits, /// Sort by descending amount of G4 energy matched to. If two /// trajectories match to the same amount of energy, sort them by /// ascending ParticleID. kG4Energy, /// Sort by ascending ParticleID. kParticleID }; /// Which types of hits to truth-match against. enum Views { /// Only match to XZ hits. kXZ, /// Only match to YZ hits. kYZ, /// Only match to XY hits. kXY, /// Match to all hits. kXYZ, /// None of the above. kViewNotSet }; /// Basic constructor that does no work. IShowerTruthInfo(); /// Computationally expensive constructor for truth-matching a IReconBase /// object. Define which algorithms to run using enableSingle, /// enablePrimary and enableRecursive parameters; IShowerTruthInfo(COMET::IHandle object, bool enableSingle = true, bool enablePrimary = true, bool enableRecursive = true); /// Computationally expensive constructor for truth-matching a /// IHitSelection. The views parameter defines which hits should be used /// when matching. Define which algorithms to run using enableSingle, /// enablePrimary and enableRecursive parameters; IShowerTruthInfo(COMET::IHandle hits, Views views, bool enableSingle = true, bool enablePrimary = true, bool enableRecursive = true); virtual ~IShowerTruthInfo(); /// Computationally expensive routine for calculating truth-matching a /// IReconBase object. /// See the equivalent constructor for full documentation. void FillFromObject(COMET::IHandle object, bool enableSingle = true, bool enablePrimary = true, bool enableRecursive = true); /// Computationally expensive routine for calculating truth-matching a /// IHitSelection. /// See the equivalent constructor for full documentation. void FillFromHits(COMET::IHandle hits, Views views, bool enableSingle = true, bool enablePrimary = true, bool enableRecursive = true); /// Get the results of the "single trajectory" truth-matching algorithm. /// /// This algorithm is equivalent to the oaUtility TrackTruthInfo method of /// matching. /// /// Each entry in the returned vector corresponds to a single trajectory /// which contributed to the input object. /// /// The completeness and cleanliness figures are based on the single /// trajectory only. std::vector GetSingleTrajectories(SortOrder order = kNumHits); /// Get the results of the "primary trajectory" truth-matching algorithm. /// /// Each entry in the returned vector corresponds to a single primary /// particle whose daughters contributed to the input object. /// /// The completeness and cleanliness figures are based on all the daughter /// trajectories that enter the subdetectors used by the specified /// IReconBase/IHitSelection. /// /// It is advised that this method is only used when the primary particle /// of interest is known to have entered the subdetector the input object /// uses. std::vector GetPrimaryTrajectories(SortOrder order = kNumHits); /// Get the results of the "recursive trajectory" truth-matching algorithm. /// /// Each entry in the returned vector corresponds to a single particle that /// meets the following criteria: /// * Enters one of the subdetectors used by the input object. /// * Has daughters that contribute to the input object, or contributes to /// the object itself. /// * Has no parent non-neutrino particles that also enter the subdetectors /// used. /// /// The completeness and cleanliness figures are based on all the daughters /// of the matched trajectory that enter the subdetectors used. std::vector GetRecursiveTrajectories(SortOrder order = kNumHits); private: /// The three truth-matching algorithms that are available. enum Algorithm { kSingle, kRecursive, kPrimary }; /// Class used to sort TruthInfo structs by decreasing number of hits /// matched to. If two objects have the same number of hits, they are /// sorted by increasing ParticleID. class ISortByNumHits { public: inline bool operator()(const TruthInfo &lhs, const TruthInfo &rhs) { return (lhs.NumHits > rhs.NumHits || (lhs.NumHits == rhs.NumHits && lhs.ParticleID < rhs.ParticleID)); } }; /// Class used to sort TruthInfo structs by decreasing amount of G4 energy /// matched to. If two objects have the same number of hits, they are /// sorted by increasing ParticleID. class ISortByG4Energy { public: inline bool operator()(const TruthInfo &lhs, const TruthInfo &rhs) { return (lhs.G4Energy > rhs.G4Energy || (lhs.G4Energy == rhs.G4Energy && lhs.ParticleID < rhs.ParticleID)); } }; /// Class used to sort results by increasing ParticleID number. class ISortByParticleID { public: inline bool operator()(const TruthInfo &lhs, const TruthInfo &rhs) { return lhs.ParticleID < rhs.ParticleID; } }; private: /// For a given particle, map from the channel ID of a hit to the amount of /// G4 energy this particle contributed to that channel. We must keep track /// of the channel IDs so we don't double count hits. typedef std::map HitDetails; /// Map from a particle ID to the details of the hits caused by that /// particle. typedef std::map ParticleDetails; /// A vector of particle IDs. typedef std::vector ParticleList; /// A map from a given particle ID to the relevant descendants of that /// particle. typedef std::map ParticleTree; /// Clean up the details of current results. void Reset(); /// Note that a trajectory contributes to the input object. void MarkSingleTrajectory(int trajID); /// Note the relationship between a trajectory and its primary. Should only /// be called for primaries who have a daughter that contributes to the /// input object. void MarkPrimaryTrajectory(int trajID, int primaryID); /// Calculate all the parent-child relationships for particles that are /// relevant to the recursive matching algorithm. void MarkRecursiveTrajectories(); /// Whether all the parents (working recursively upwards) are irrelevant to /// the recursive truth matching. The singleTrajRelevant object specifies /// which individual trajectories enter the subdetectors used by the input /// hit selection. bool AllParentsIrrelevant(COMET::IHandle traj, std::map &singleTrajRelevant); /// Whether all the children (working recursively downwards) are irrelevant /// to the recursive truth matching. The singleTrajRelevant object /// specifies which individual trajectories enter the subdetectors used by /// the input hit selection. The parentChildMap object specifies the /// parent-child links for all the trajectories in the event. bool AllChildrenIrrelevant(COMET::IHandle traj, std::map &singleTrajRelevant, ParticleTree &parentChildMap); /// Calculate the total number of hits and total amount of G4 energy used /// in the input object. These numbers are used to calculate the /// cleanliness figures. void GetReconStats(int &totalRecoHits, double &totalRecoEnergy); /// Calculate the completenesses and cleanlinesses for all 3 algorithms. void CalculateStatistics(); /// Calculate the completenesses and cleanlinesses for the given /// algorithm. The totalRecoHits and totalRecoEnergy parameters are used to /// calculate the cleanliness figures. std::vector CalculateStatistics(double totalRecoHits, double totalRecoEnergy, Algorithm type); /// Calculate the number of hits and amount of G4 energy a single /// trajectory contributed. The "details" object can contain the low-level /// information for either the input hit selection, or for all hits in the /// event. void GetSingleNumHitsEnergy(int trajID, ParticleDetails &details, int& numHits, double& energy); /// Calculate the number of hits and amount of G4 energy a primary /// trajectory and all its daughters contributed. The "details" object can /// contain the low-level information for either the input hit selection, /// or for all hits in the event. The function is called recursively if one /// of the daughters of this primary is also a primary. void GetPrimaryNumHitsEnergy(int trajID, ParticleDetails &details, int& numHits, double& energy); /// Calculate the number of hits and amount of G4 energy a primary /// trajectory and all its daughters contributed. The "details" object can /// contain the low-level information for either the input hit selection, /// or for all hits in the event. The function is called recursively if one /// of the daughters of this primary is also a primary. The usedChannels /// parameter ensures we don't double count hits that are used by more than /// one daughter. The usedPrimaries parameter keeps track of the particles /// we've looked at so we don't get into an infinite loop (a very rare edge /// case). void GetPrimaryNumHitsEnergy(int trajID, ParticleDetails &details, int& numHits, double& energy, std::vector& usedChannels, std::vector& usedPrimaries); /// Calculate the number of hits and amount of G4 energy a top-level /// trajectory and all its daughters contributed. The "details" object can /// contain the low-level information for either the input hit selection, /// or for all hits in the event. The function is called recursively for all /// the daughters of this particle. void GetRecursiveNumHitsEnergy(int trajID, ParticleDetails &details, int& numHits, double& energy); /// Calculate the number of hits and amount of G4 energy a top-level /// trajectory and all its daughters contributed. The "details" object can /// contain the low-level information for either the input hit selection, /// or for all hits in the event. The function is called recursively for all /// the daughters of this particle. The usedChannels parameter ensures we /// don't double count hits that are used by more than one daughter. void GetRecursiveNumHitsEnergy(int trajID, ParticleDetails &details, int& numHits, double& energy, std::vector& usedChannels); /// Get the total amount of G4 energy that contributed to a hit. If the hit /// is purely noise, uses the fDarkNoiseEnergy parameter to estimate an /// approximately equivalent amount of G4 energy. double GetG4EnergyOfHit(COMET::IHandle hit); /// Fill the fSelecDetails object with the truth-matching information of /// all the hits in the input hit selection. void FillSelectionTruthDetails(); /// Fill the fEventDetails object with the truth-matching information of /// all the hits in the event that are in the same subdetectors used by /// the input hit selection. void FillEventTruthDetails(); /// Extract the information of which true trajectories contributed to the /// hits in the hit selections. Fills the "details" object with the /// extracted information. /// The eventLevel parameter specifies whether we're looking at the input /// hit selection (false) or a hit selection from all the hits in the event /// (true). void FillTruthDetails(COMET::IHitSelection* hits, ParticleDetails &details, bool eventLevel); /// Extract the information of which true trajectories contributed to a /// hit. Fills the "details" object with the extracted information. /// The eventLevel parameter specifies whether we're looking at a hit from /// the input hit selection (false) or from a hit selection from all the /// hits in the event (true). void FillTruthDetails(COMET::IHandle &hit, ParticleDetails &details, bool eventLevel); /// Work out which views the object uses. Views GetViews(COMET::IHandle object); /// Sort a std::vector according in a given order. std::vector SortResult(std::vector result, SortOrder order); /// Whether to run the single trajectory truth-matching algorithm. bool fEnableSingle; /// Whether to run the primary trajectory truth-matching algorithm. bool fEnablePrimary; /// Whether to run the recursive trajectory truth-matching algorithm. bool fEnableRecursive; /// The hits passed in by the user (or the hits of the IReconBase passed /// in). COMET::IHandle fHits; /// The detectors used by the input object. int fDetectorsUsed; /// The views to look for hits in. Views fViews; /// Information of which hits in the input hit selection each true /// trajectory matches to. ParticleDetails fSelecDetails; /// Information of which hits each true trajectory matches to. The hits /// used here are all the hits in the same subdetectors as the subdetectors /// used by the input object. ParticleDetails fEventDetails; /// List of all the trajectories that contributed to the input object. /// The "single trajectory" matching algorithm calculates the stats /// for each element in this list. ParticleList fSingleTrajList; /// List of all the primary trajectories that have daughters that /// contributed to the input object, or that contibuted themselves. The /// "primary trajectory" matching algorithm calculates the stats for each /// element in this list. ParticleList fPrimaryTrajList; /// Specify the relationship between a primary particle and all of its /// daughters that causes hits in the subdetectors used by the input /// object. ParticleTree fPrimaryTrajHierarchy; /// List of all the highest-level non-neutrino trajectories that enter the /// subdector used by the input object and have daughters that contributed /// to the input object, or that contibuted themselves. The "recursive /// trajectory" matching algorithm calculates the stats for each element in /// this list. ParticleList fRecursiveTrajList; /// Specify the parent-child relationships for all trajectories relevant to /// the recursive matching algorithm. A trajectory is not relevant if it /// doesn't enter the subdetectors used by the input object, and either /// * none of its parents enter (working recursively upwards) /// * none of its daughters enter (working recursively downwards). ParticleTree fRecursiveTrajHierarchy; /// Internal representation of the results of the single trajectory truth- /// matching algorithm. The results are sorted before being presented to /// the user. std::vector fSingleTrajectoryResults; /// Internal representation of the results of the primary trajectory truth- /// matching algorithm. The results are sorted before being presented to /// the user. std::vector fPrimaryTrajectoryResults; /// Internal representation of the results of the recursive trajectory /// truth-matching algorithm. The results are sorted before being presented /// to the user. std::vector fRecursiveTrajectoryResults; /// The amount of G4 energy to assign to a noise hit. double fDarkNoiseEnergy; }; #endif