Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-12-17 09:21:20

0001 /// ===========================================================================
0002 /*! \file   TrksInJetQAInJetFiller.cc
0003  *  \author Derek Anderson
0004  *  \date   04.03.2024
0005  *
0006  *  A submodule for the TrksInJetsQAM F4A module to produce
0007  *  QA histograms for tracks and more in jets
0008  */
0009 /// ===========================================================================
0010 
0011 
0012 // submodule definition
0013 #include "TrksInJetQAInJetFiller.h"
0014 
0015 // inherited public methods ===================================================
0016 
0017 // ----------------------------------------------------------------------------
0018 //! Run fill for relevant histograms
0019 // ----------------------------------------------------------------------------
0020 void TrksInJetQAInJetFiller::Fill(PHCompositeNode* topNode)
0021 {
0022   GetNodes(topNode);
0023 
0024   FillJetAndTrackQAHists(topNode);
0025 }  // end 'Fill(PHCompositeNode* topNode)'
0026 
0027 // private methods ============================================================
0028 
0029 // ----------------------------------------------------------------------------
0030 //! Grab additional input nodes
0031 // ----------------------------------------------------------------------------
0032 void TrksInJetQAInJetFiller::GetNode(const int node, PHCompositeNode* topNode)
0033 {
0034   // jump to relevant node
0035   // NOLINTNEXTLINE(hicpp-multiway-paths-covered)
0036   switch (node)
0037   {
0038     case Node::Flow:
0039       m_flowStore = findNode::getClass<ParticleFlowElementContainer>(topNode, "ParticleFlowElements");
0040       if (!m_flowStore)
0041       {
0042         std::cerr << PHWHERE << ": PANIC: Couldn't grab particle flow container from node tree!" << std::endl;
0043         assert(m_flowStore);
0044       }
0045       break;
0046     default:
0047       std::cerr << PHWHERE << ": WARNING: trying to grab unkown additional node..." << std::endl;
0048       break;
0049   }
0050 }  // end 'GetNode(int, PHCompositeNode*)'
0051 
0052 // ----------------------------------------------------------------------------
0053 //! Fill histograms for jet and in-jet track histograms
0054 // ----------------------------------------------------------------------------
0055 /*! This defines how to (1) loop over jets, and (2) extract
0056  *  tracks inside them. Some care is required here since
0057  *  jets can be made
0058  *    a. completely without tracks (e.g. from calo towers),
0059  *    b. completely with tracks (i.e. track jets),
0060  *    c. or with a mix of tracks and other objects (e.g.
0061  *       particle flow jets).
0062  *  Once tracks have been identified, the relevant hit and
0063  *  cluster populations are extracted from the tracks, and
0064  *  their histograms are filled.
0065  */
0066 void TrksInJetQAInJetFiller::FillJetAndTrackQAHists(PHCompositeNode* topNode)
0067 {
0068   // loop over jets
0069   for (
0070       uint64_t iJet = 0;
0071       iJet < m_jetMap->size();
0072       ++iJet)
0073   {
0074     // grab jet and make sure track vector is clear
0075     Jet* jet = m_jetMap->get_jet(iJet);
0076     m_trksInJet.clear();
0077 
0078     // get all tracks "in" a jet
0079     GetCstTracks(jet, topNode);
0080     GetNonCstTracks(jet);
0081 
0082     // grab jet info and fill histograms
0083     if (m_config.doJetQA)
0084     {
0085       m_jetManager->GetInfo(jet, m_trksInJet);
0086     }
0087 
0088     // loop over tracks in the jet
0089     for (SvtxTrack* track : m_trksInJet)
0090     {
0091       // grab track info and fill histograms
0092       if (m_config.doTrackQA)
0093       {
0094         m_trackManager->GetInfo(track, jet);
0095       }
0096 
0097       // fill cluster and hit histograms as needed
0098       if (m_config.doClustQA || m_config.doHitQA)
0099       {
0100         FillClustAndHitQAHists(track);
0101       }
0102     }  // end track loop
0103   }  // end jet loop
0104 }  // end 'FillJetAndTrackQAHists(PHCompositeNode*)'
0105 
0106 // ----------------------------------------------------------------------------
0107 //! Fill histograms for in-jet track hits and clusters
0108 // ----------------------------------------------------------------------------
0109 void TrksInJetQAInJetFiller::FillClustAndHitQAHists(SvtxTrack* track)
0110 {
0111   // get cluster keys
0112   for (auto clustKey : ClusKeyIter(track))
0113   {
0114     // grab cluster and its info
0115     if (m_config.doClustQA)
0116     {
0117       m_clustManager->GetInfo(
0118           m_clustMap->findCluster(clustKey),
0119           clustKey,
0120           m_actsGeom);
0121     }
0122 
0123     // get hits if needed
0124     if (m_config.doHitQA)
0125     {
0126       // grab hit set and key associated with cluster key
0127       TrkrDefs::hitsetkey setKey = TrkrDefs::getHitSetKeyFromClusKey(clustKey);
0128       TrkrHitSet* set = m_hitMap->findHitSet(setKey);
0129       if (!set || !(set->size() > 0))
0130       {
0131         return;
0132       }
0133 
0134       // loop over all hits in hit set
0135       TrkrHitSet::ConstRange hits = set->getHits();
0136       for (
0137           TrkrHitSet::ConstIterator itHit = hits.first;
0138           itHit != hits.second;
0139           ++itHit)
0140       {
0141         // grab hit
0142         TrkrDefs::hitkey hitKey = itHit->first;
0143         TrkrHit* hit = itHit->second;
0144 
0145         // grab info and fill histograms
0146         m_hitManager->GetInfo(hit, setKey, hitKey);
0147 
0148       }  // end hit loop
0149     }
0150   }  // end cluster key loop
0151 }  // end 'FillClustQAHists(SvtxTrack*)'
0152 
0153 // ----------------------------------------------------------------------------
0154 //! Identify constituent tracks in a jet
0155 // ----------------------------------------------------------------------------
0156 void TrksInJetQAInJetFiller::GetCstTracks(Jet* jet, PHCompositeNode* topNode)
0157 {
0158   // loop over consituents
0159   auto csts = jet->get_comp_vec();
0160   for (auto& cst : csts)
0161   {
0162     // ignore cst if non-relevent type
0163     const uint32_t src = cst.first;
0164     if (IsCstNotRelevant(src))
0165     {
0166       continue;
0167     }
0168 
0169     // if cst is track, add to list
0170     if (src == Jet::SRC::TRACK)
0171     {
0172       m_trksInJet.push_back(m_trkMap->get(cst.second));
0173     }
0174 
0175     // if pfo, grab track if needed
0176     if (src == Jet::SRC::PARTICLE)
0177     {
0178       TrksInJetQADefs::PFObject* pfo = GetPFObject(cst.second, topNode);
0179       SvtxTrack* track = GetTrkFromPFO(pfo);
0180       if (track)
0181       {
0182         m_trksInJet.push_back(track);
0183       }
0184     }
0185   }  // end cst loop
0186 }  // end 'GetCstTracks(Jet* jet, PHCompositeNode* topNode)'
0187 
0188 // ----------------------------------------------------------------------------
0189 //! Identify tracks in jet cone that are NOT constituents
0190 // ----------------------------------------------------------------------------
0191 /*! This method comes into play if, e.g., the jets being
0192  *  analyzed were made with calorimeter information only.
0193  *  In this case you can still have tracks lying inside
0194  *  the jet cone despite them not being consituents of
0195  *  the constructed jet.
0196  */
0197 void TrksInJetQAInJetFiller::GetNonCstTracks(Jet* jet)
0198 {
0199   // loop over tracks
0200   for (auto& itTrk : *m_trkMap)
0201   {
0202     // grab track
0203     SvtxTrack* track = itTrk.second;
0204 
0205     // ignore tracks we've already added to the list
0206     if (IsTrkInList(track->get_id()))
0207     {
0208       continue;
0209     }
0210 
0211     // FIXME this can be improved!
0212     //   - jets don't necessarily have areas of
0213     //     pi*(Rjet)^2
0214     //   - it may be better to instead check
0215     //     if a track projection falls in
0216     //     a constituent tower/cluster
0217     //   - Also track projections to a calo
0218     //     would be better to use than just
0219     //     the track
0220     const double dr = GetTrackJetDist(track, jet);
0221     if (dr < m_config.rJet)
0222     {
0223       m_trksInJet.push_back(track);
0224     }
0225   }  // end track loop
0226 }  // end 'GetNonCstTracks(Jet* jet)'
0227 
0228 // ----------------------------------------------------------------------------
0229 //! Check if a consituent is not a relevant type
0230 // ----------------------------------------------------------------------------
0231 bool TrksInJetQAInJetFiller::IsCstNotRelevant(const uint32_t type)
0232 {
0233   const bool isVoid = (type == Jet::SRC::VOID);
0234   const bool isImport = (type == Jet::SRC::HEPMC_IMPORT);
0235   const bool isProbe = (type == Jet::SRC::JET_PROBE);
0236   return (isVoid || isImport || isProbe);
0237 }  // end 'IsCstNotRelevant(uint32_t)'
0238 
0239 // ----------------------------------------------------------------------------
0240 //! Check if a track has already been added to the list of tracks in the jet
0241 // ----------------------------------------------------------------------------
0242 bool TrksInJetQAInJetFiller::IsTrkInList(const uint32_t id)
0243 {
0244   bool isAdded = false;
0245   for (SvtxTrack* trkInJet : m_trksInJet)
0246   {
0247     if (id == trkInJet->get_id())
0248     {
0249       isAdded = true;
0250       break;
0251     }
0252   }
0253   return isAdded;
0254 }  // end 'IsTrkInList(uint32_t)'
0255 
0256 // ----------------------------------------------------------------------------
0257 //! Get eta-phi distance between track & jet axis
0258 // ----------------------------------------------------------------------------
0259 double TrksInJetQAInJetFiller::GetTrackJetDist(SvtxTrack* track, Jet* jet)
0260 {
0261   // get delta eta
0262   const double dEta = (track->get_eta()) - (jet->get_eta());
0263 
0264   // get delta phi
0265   double dPhi = (track->get_phi()) - (jet->get_phi());
0266   if (dPhi < (-1. * M_PI))
0267   {
0268     dPhi += 2. * M_PI;
0269   }
0270   if (dPhi > (1. * M_PI))
0271   {
0272     dPhi -= 2. * M_PI;
0273   }
0274 
0275   // return distance
0276   return std::hypot(dEta, dPhi);
0277 
0278 }  // end 'GetTrackJetDist(SvtxTrack*, Jet*)'
0279 
0280 // ----------------------------------------------------------------------------
0281 //! Find a particle flow element in node
0282 // ----------------------------------------------------------------------------
0283 TrksInJetQADefs::PFObject* TrksInJetQAInJetFiller::GetPFObject(const uint32_t id,
0284                                                                PHCompositeNode* topNode)
0285 {
0286   // pointer to pfo
0287   TrksInJetQADefs::PFObject* pfoToFind = nullptr;
0288 
0289   // grab pf node if needed
0290   if (!m_flowStore)
0291   {
0292     GetNode(Node::Flow, topNode);
0293   }
0294 
0295   // loop over pfos
0296   for (
0297       ParticleFlowElementContainer::ConstIterator itFlow = m_flowStore->getParticleFlowElements().first;
0298       itFlow != m_flowStore->getParticleFlowElements().second;
0299       ++itFlow)
0300   {
0301     // get pfo
0302     TrksInJetQADefs::PFObject* pfo = itFlow->second;
0303 
0304     // if has provided id, set pointer and exit
0305     if (id == pfo->get_id())
0306     {
0307       pfoToFind = pfo;
0308       break;
0309     }
0310   }  // end pfo loop
0311   return pfoToFind;
0312 }  // end 'GetPFObject(uint32_t, PHCompositeNode*)'
0313 
0314 // ----------------------------------------------------------------------------
0315 //! Get track from a particle flow element
0316 // ----------------------------------------------------------------------------
0317 SvtxTrack* TrksInJetQAInJetFiller::GetTrkFromPFO(TrksInJetQADefs::PFObject* pfo)
0318 {
0319   // pointer to track
0320   SvtxTrack* track = nullptr;
0321 
0322   // if pfo has track, try to grab
0323   const auto type = pfo->get_type();
0324   if (
0325       (type == ParticleFlowElement::PFLOWTYPE::MATCHED_CHARGED_HADRON) ||
0326       (type == ParticleFlowElement::PFLOWTYPE::UNMATCHED_CHARGED_HADRON))
0327   {
0328     track = pfo->get_track();
0329   }
0330   return track;
0331 }  // end 'GetTrkFromPFO(TrksInJetQADefs::PFObject*)'
0332 
0333 // end ========================================================================