Back to home page

sPhenix code displayed by LXR

 
 

    


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

0001 #include "QAG4SimulationKFParticle.h"
0002 
0003 #include <qautils/QAHistManagerDef.h>  // for getHistoManager
0004 
0005 #include <kfparticle_sphenix/KFParticle_Container.h>
0006 #include <kfparticle_sphenix/KFParticle_Tools.h>
0007 
0008 #include <g4eval/SvtxClusterEval.h>
0009 #include <g4eval/SvtxEvalStack.h>  // for SvtxEvalStack
0010 
0011 #include <g4main/PHG4Particle.h>
0012 #include <g4main/PHG4TruthInfoContainer.h>
0013 
0014 #include <trackbase_historic/SvtxTrack.h>  // for SvtxTrack
0015 #include <trackbase_historic/SvtxTrackMap.h>
0016 
0017 #include <trackbase/TrkrDefs.h>  // for cluskey
0018 
0019 #include <phhepmc/PHHepMCGenEvent.h>
0020 #include <phhepmc/PHHepMCGenEventMap.h>
0021 
0022 #include <fun4all/Fun4AllHistoManager.h>
0023 #include <fun4all/Fun4AllReturnCodes.h>
0024 #include <fun4all/SubsysReco.h>
0025 
0026 #include <phool/getClass.h>
0027 
0028 #include <KFParticle.h>
0029 
0030 #include <HepMC/GenEvent.h>
0031 #include <HepMC/GenParticle.h>
0032 #include <HepMC/GenVertex.h>
0033 #include <HepMC/IteratorRange.h>
0034 
0035 #include <TH1.h>
0036 #include <TString.h>
0037 
0038 #include <CLHEP/Vector/LorentzVector.h>
0039 #include <CLHEP/Vector/ThreeVector.h>
0040 
0041 #include <cassert>
0042 #include <cstdlib>  // for abs, NULL
0043 #include <iostream>
0044 #include <map>
0045 #include <string>
0046 #include <utility>  // for pair
0047 #include <vector>
0048 
0049 namespace
0050 {
0051   KFParticle_Tools kfpTools;
0052 }
0053 
0054 QAG4SimulationKFParticle::QAG4SimulationKFParticle(const std::string &name, const std::string &mother_name, double min_m, double max_m)
0055   : SubsysReco(name)
0056   , m_mother_id(kfpTools.getParticleID(mother_name))
0057   , m_min_mass(min_m)
0058   , m_max_mass(max_m)
0059   , m_mother_name(mother_name)
0060 {
0061 }
0062 
0063 int QAG4SimulationKFParticle::InitRun(PHCompositeNode *topNode)
0064 {
0065   if (!m_svtxEvalStack)
0066   {
0067     m_svtxEvalStack.reset(new SvtxEvalStack(topNode));
0068     m_svtxEvalStack->set_strict(false);
0069     m_svtxEvalStack->set_verbosity(Verbosity());
0070   }
0071   m_trackMap = findNode::getClass<SvtxTrackMap>(topNode, m_trackMapName);
0072   if (!m_trackMap)
0073   {
0074     std::cout << __PRETTY_FUNCTION__ << " Fatal Error : missing " << m_trackMapName << std::endl;
0075     return Fun4AllReturnCodes::ABORTRUN;
0076   }
0077 
0078   m_truthInfo = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
0079   if (!m_trackMap)
0080   {
0081     std::cout << __PRETTY_FUNCTION__ << " Fatal Error : missing G4TruthInfo" << std::endl;
0082     return Fun4AllReturnCodes::ABORTRUN;
0083   }
0084 
0085   return Fun4AllReturnCodes::EVENT_OK;
0086 }
0087 
0088 int QAG4SimulationKFParticle::Init(PHCompositeNode * /*topNode*/)
0089 {
0090   Fun4AllHistoManager *hm = QAHistManagerDef::getHistoManager();
0091   assert(hm);
0092 
0093   TH1 *h(nullptr);
0094 
0095   h = new TH1F(TString(get_histo_prefix()) + "InvMass",
0096                ";mass [GeV/c^{2}];Entries", 100, m_min_mass, m_max_mass);
0097   hm->registerHisto(h);
0098 
0099   h = new TH1F(TString(get_histo_prefix()) + "InvMass_KFP",
0100                ";mass [GeV/c^{2}];Entries", 100, m_min_mass, m_max_mass);
0101   hm->registerHisto(h);
0102 
0103   h = new TH1F(TString(get_histo_prefix()) + "DecayTime",
0104                ";Decay Time [ps];Entries", 100, 0, 1.5);
0105   hm->registerHisto(h);
0106 
0107   h = new TH1F(TString(get_histo_prefix()) + "pT",
0108                ";pT [GeV/c];Entries", 100, 0, 10);
0109   hm->registerHisto(h);
0110 
0111   h = new TH1F(TString(get_histo_prefix()) + "Chi2_NDF",
0112                ";#chi^{2}/NDF ;Entries", 100, 0, 5);
0113   hm->registerHisto(h);
0114 
0115   h = new TH1F(TString(get_histo_prefix()) + "Rapidity",
0116                ";y;Entries", 100, -2, 2);
0117   hm->registerHisto(h);
0118 
0119   h = new TH1F(TString(get_histo_prefix()) + "Mother_DCA_XY",
0120                ";DCA [cm];Entries", 100, -0.05, 0.05);
0121   hm->registerHisto(h);
0122 
0123   h = new TH1F(TString(get_histo_prefix()) + "Daughter1_pT",
0124                ";pT [GeV/c];Entries", 100, 0, 10);
0125   hm->registerHisto(h);
0126   h = new TH1F(TString(get_histo_prefix()) + "Daughter2_pT",
0127                ";pT [GeV/c];Entries", 100, 0, 10);
0128   hm->registerHisto(h);
0129   h = new TH1F(TString(get_histo_prefix()) + "Daughter3_pT",
0130                ";pT [GeV/c];Entries", 100, 0, 10);
0131   hm->registerHisto(h);
0132   h = new TH1F(TString(get_histo_prefix()) + "Daughter4_pT",
0133                ";pT [GeV/c];Entries", 100, 0, 10);
0134   hm->registerHisto(h);
0135 
0136   h = new TH1F(TString(get_histo_prefix()) + "Daughter1_DCA_XY_Mother",
0137                ";DCA [cm];Entries", 100, -0.05, 0.05);
0138   hm->registerHisto(h);
0139   h = new TH1F(TString(get_histo_prefix()) + "Daughter2_DCA_XY_Mother",
0140                ";DCA [cm];Entries", 100, -0.05, 0.05);
0141   hm->registerHisto(h);
0142   h = new TH1F(TString(get_histo_prefix()) + "Daughter3_DCA_XY_Mother",
0143                ";DCA [cm];Entries", 100, -0.05, 0.05);
0144   hm->registerHisto(h);
0145   h = new TH1F(TString(get_histo_prefix()) + "Daughter4_DCA_XY_Mother",
0146                ";DCA [cm];Entries", 100, -0.05, 0.05);
0147   hm->registerHisto(h);
0148 
0149   return Fun4AllReturnCodes::EVENT_OK;
0150 }
0151 
0152 int QAG4SimulationKFParticle::process_event(PHCompositeNode *topNode)
0153 {
0154   if (Verbosity() > 2)
0155   {
0156     std::cout << "QAG4SimulationKFParticle::process_event() entered" << std::endl;
0157   }
0158 
0159   // load relevant nodes from NodeTree
0160   load_nodes(topNode);
0161 
0162   // histogram manager
0163   Fun4AllHistoManager *hm = QAHistManagerDef::getHistoManager();
0164   assert(hm);
0165 
0166   TH1F *h_mass = dynamic_cast<TH1F *>(hm->getHisto(get_histo_prefix() + "InvMass"));
0167   assert(h_mass);
0168   TH1F *h_mass_KFP = dynamic_cast<TH1F *>(hm->getHisto(get_histo_prefix() + "InvMass_KFP"));
0169   assert(h_mass_KFP);
0170   TH1F *h_DecayTime = dynamic_cast<TH1F *>(hm->getHisto(get_histo_prefix() + "DecayTime"));
0171   assert(h_DecayTime);
0172   TH1F *h_pT = dynamic_cast<TH1F *>(hm->getHisto(get_histo_prefix() + "pT"));
0173   assert(h_pT);
0174   TH1F *h_Chi2_NDF = dynamic_cast<TH1F *>(hm->getHisto(get_histo_prefix() + "Chi2_NDF"));
0175   assert(h_Chi2_NDF);
0176   TH1F *h_Rapidity = dynamic_cast<TH1F *>(hm->getHisto(get_histo_prefix() + "Rapidity"));
0177   assert(h_Rapidity);
0178   TH1F *h_Mother_DCA_XY = dynamic_cast<TH1F *>(hm->getHisto(get_histo_prefix() + "Mother_DCA_XY"));
0179   assert(h_Mother_DCA_XY);
0180   TH1F *h_Daughter1_pT = dynamic_cast<TH1F *>(hm->getHisto(get_histo_prefix() + "Daughter1_pT"));
0181   assert(h_Daughter1_pT);
0182   TH1F *h_Daughter1_DCA_XY_Mother = dynamic_cast<TH1F *>(hm->getHisto(get_histo_prefix() + "Daughter1_DCA_XY_Mother"));
0183   assert(h_Daughter1_DCA_XY_Mother);
0184   TH1F *h_Daughter2_pT = dynamic_cast<TH1F *>(hm->getHisto(get_histo_prefix() + "Daughter2_pT"));
0185   assert(h_Daughter2_pT);
0186   TH1F *h_Daughter2_DCA_XY_Mother = dynamic_cast<TH1F *>(hm->getHisto(get_histo_prefix() + "Daughter2_DCA_XY_Mother"));
0187   assert(h_Daughter2_DCA_XY_Mother);
0188   TH1F *h_Daughter3_pT = dynamic_cast<TH1F *>(hm->getHisto(get_histo_prefix() + "Daughter3_pT"));
0189   assert(h_Daughter3_pT);
0190   TH1F *h_Daughter3_DCA_XY_Mother = dynamic_cast<TH1F *>(hm->getHisto(get_histo_prefix() + "Daughter3_DCA_XY_Mother"));
0191   assert(h_Daughter3_DCA_XY_Mother);
0192   TH1F *h_Daughter4_pT = dynamic_cast<TH1F *>(hm->getHisto(get_histo_prefix() + "Daughter4_pT"));
0193   assert(h_Daughter4_pT);
0194   TH1F *h_Daughter4_DCA_XY_Mother = dynamic_cast<TH1F *>(hm->getHisto(get_histo_prefix() + "Daughter4_DCA_XY_Mother"));
0195   assert(h_Daughter4_DCA_XY_Mother);
0196 
0197   if (m_svtxEvalStack)
0198   {
0199     m_svtxEvalStack->next_event(topNode);
0200   }
0201 
0202   std::vector<CLHEP::HepLorentzVector> daughters;
0203   for (auto &[key, track] : *m_trackMap)
0204   {
0205     SvtxTrack *thisTrack = getTrack(key, m_trackMap);
0206     CLHEP::HepLorentzVector *theVector = makeHepLV(topNode, thisTrack->get_id());
0207     if (theVector)
0208     {
0209       daughters.push_back(*theVector);
0210     }
0211   }
0212 
0213   CLHEP::HepLorentzVector mother;
0214   if (daughters.size() >= 2)
0215   {
0216     for (const CLHEP::HepLorentzVector &daughter : daughters)
0217     {
0218       mother += daughter;
0219     }
0220   }
0221 
0222   h_mass->Fill(mother.m());
0223 
0224   daughters.clear();
0225 
0226   float m_calculated_mother_decaytime = -1;
0227   float m_calculated_mother_decaytime_err = -1;
0228   const float speedOfLight = 2.99792458e-1;
0229 
0230   // std::map<unsigned int, KFParticle*> Map = m_kfpContainer->returnParticlesByPDGid(m_mother_id);
0231   std::vector<int> d_id;
0232   std::vector<KFParticle> vertex_vec = kfpTools.makeAllPrimaryVertices(topNode, "SvtxVertexMap");
0233 
0234   for (auto &iter : *m_kfpContainer)
0235   {
0236     if (iter.second->GetPDG() != m_mother_id)
0237     {
0238       if (d_id.empty())
0239       {
0240         d_id.push_back(abs(iter.second->GetPDG()));
0241       }
0242       else
0243       {
0244         for (unsigned int j = 0; j < d_id.size(); ++j)
0245         {
0246           if (abs(iter.second->GetPDG()) == d_id[j])
0247           {
0248             continue;
0249           }
0250           if (j == d_id.size() - 1)
0251           {
0252             d_id.push_back(abs(iter.second->GetPDG()));
0253           }
0254         }
0255       }
0256     }
0257   }
0258 
0259   for (auto &iter : *m_kfpContainer)
0260   {
0261     if (iter.second->GetPDG() == m_mother_id)
0262     {
0263       // filling mother histogram information
0264       h_mass_KFP->Fill(iter.second->GetMass());
0265       // h_DecayTime->Fill(part->GetLifeTime());
0266       h_pT->Fill(iter.second->GetPt());
0267       h_Chi2_NDF->Fill(iter.second->Chi2() / iter.second->NDF());
0268       h_Rapidity->Fill(iter.second->GetRapidity());
0269       // best PV fit for mother
0270       int bestCombinationIndex = 0;
0271       if (!vertex_vec.empty())
0272       {
0273         for (unsigned int i = 1; i < vertex_vec.size(); ++i)
0274         {
0275           if (iter.second->GetDeviationFromVertex(vertex_vec[i]) <
0276               iter.second->GetDeviationFromVertex(vertex_vec[bestCombinationIndex]))
0277           {
0278             bestCombinationIndex = i;
0279           }
0280         }
0281         h_Mother_DCA_XY->Fill(iter.second->GetDistanceFromVertexXY(vertex_vec[bestCombinationIndex]));
0282 
0283         iter.second->SetProductionVertex(vertex_vec[bestCombinationIndex]);
0284         iter.second->GetLifeTime(m_calculated_mother_decaytime, m_calculated_mother_decaytime_err);
0285         // part->GetDecayLength(m_calculated_mother_decaylength, m_calculated_mother_decaylength_err);
0286         m_calculated_mother_decaytime /= speedOfLight;
0287         // m_calculated_mother_decaytime_err /= speedOfLight;
0288 
0289         h_DecayTime->Fill(m_calculated_mother_decaytime);
0290 
0291         for (unsigned int i = 0; i < d_id.size(); ++i)
0292         {
0293           std::map<unsigned int, KFParticle *> const D_Map = m_kfpContainer->returnParticlesByPDGid(d_id[i]);
0294           for (const auto &[key, part] : D_Map)
0295           {
0296             if (i == 0)
0297             {
0298               h_Daughter1_pT->Fill(part->GetPt());
0299               h_Daughter1_DCA_XY_Mother->Fill(part->GetDistanceFromVertexXY(vertex_vec[bestCombinationIndex]));
0300             }
0301             if (i == 1)
0302             {
0303               h_Daughter2_pT->Fill(part->GetPt());
0304               h_Daughter2_DCA_XY_Mother->Fill(part->GetDistanceFromVertexXY(vertex_vec[bestCombinationIndex]));
0305             }
0306             if (i == 2)
0307             {
0308               h_Daughter3_pT->Fill(part->GetPt());
0309               h_Daughter3_DCA_XY_Mother->Fill(part->GetDistanceFromVertexXY(vertex_vec[bestCombinationIndex]));
0310             }
0311             if (i == 3)
0312             {
0313               h_Daughter4_pT->Fill(part->GetPt());
0314               h_Daughter4_DCA_XY_Mother->Fill(part->GetDistanceFromVertexXY(vertex_vec[bestCombinationIndex]));
0315             }
0316           }
0317         }
0318       }
0319     }
0320   }
0321   return Fun4AllReturnCodes::EVENT_OK;
0322 }
0323 
0324 SvtxTrack *QAG4SimulationKFParticle::getTrack(unsigned int track_id, SvtxTrackMap *trackmap)
0325 {
0326   SvtxTrack *matched_track = nullptr;
0327 
0328   for (auto &iter : *trackmap)
0329   {
0330     if (iter.first == track_id)
0331     {
0332       matched_track = iter.second;
0333     }
0334   }
0335 
0336   return matched_track;
0337 }
0338 
0339 PHG4Particle *QAG4SimulationKFParticle::getTruthTrack(SvtxTrack *thisTrack)
0340 {
0341   if (!clustereval)
0342   {
0343     clustereval = m_svtxEvalStack->get_cluster_eval();
0344   }
0345 
0346   TrkrDefs::cluskey const clusKey = *thisTrack->begin_cluster_keys();
0347   PHG4Particle *particle = clustereval->max_truth_particle_by_cluster_energy(clusKey);
0348 
0349   return particle;
0350 }
0351 
0352 CLHEP::HepLorentzVector *QAG4SimulationKFParticle::makeHepLV(PHCompositeNode *topNode, int track_number)
0353 {
0354   SvtxTrack *track = getTrack(track_number, m_trackMap);
0355   PHG4Particle *g4particle = getTruthTrack(track);
0356   CLHEP::HepLorentzVector *lvParticle = nullptr;
0357 
0358   PHHepMCGenEventMap *m_geneventmap = findNode::getClass<PHHepMCGenEventMap>(topNode, "PHHepMCGenEventMap");
0359   if (!m_geneventmap)
0360   {
0361     std::cout << "Missing node PHHepMCGenEventMap" << std::endl;
0362     std::cout << "You will have no mother information" << std::endl;
0363     return nullptr;
0364   }
0365 
0366   PHHepMCGenEvent *m_genevt = m_geneventmap->get(1);
0367   if (!m_genevt)
0368   {
0369     std::cout << "Missing node PHHepMCGenEvent" << std::endl;
0370     std::cout << "You will have no mother information" << std::endl;
0371     return nullptr;
0372   }
0373 
0374   HepMC::GenEvent *theEvent = m_genevt->getEvent();
0375 
0376   bool breakOut = false;
0377   for (HepMC::GenEvent::particle_const_iterator p = theEvent->particles_begin(); p != theEvent->particles_end(); ++p)
0378   {
0379     assert((*p));
0380     if ((*p)->barcode() == g4particle->get_barcode())
0381     {
0382       for (HepMC::GenVertex::particle_iterator mother = (*p)->production_vertex()->particles_begin(HepMC::parents);
0383            mother != (*p)->production_vertex()->particles_end(HepMC::parents); ++mother)
0384       {
0385         if (abs((*mother)->pdg_id()) == m_mother_id)
0386         {
0387           lvParticle = new CLHEP::HepLorentzVector();
0388           lvParticle->setVectM(CLHEP::Hep3Vector(track->get_px(), track->get_py(), track->get_pz()), kfpTools.getParticleMass((*p)->pdg_id()));
0389         }
0390         else
0391         {
0392           continue;
0393         }
0394         break;
0395       }
0396       breakOut = true;
0397     }
0398     if (breakOut)
0399     {
0400       break;
0401     }
0402   }
0403 
0404   return lvParticle;
0405 }
0406 
0407 int QAG4SimulationKFParticle::load_nodes(PHCompositeNode *topNode)
0408 {
0409   m_truthContainer = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
0410   if (!m_truthContainer)
0411   {
0412     std::cout << "QAG4SimulationTracking::load_nodes - Fatal Error - "
0413               << "unable to find DST node "
0414               << "G4TruthInfo" << std::endl;
0415     assert(m_truthContainer);
0416   }
0417   m_kfpContainer = findNode::getClass<KFParticle_Container>(topNode, m_mother_name + "_KFParticle_Container");
0418   if (!m_kfpContainer)
0419   {
0420     std::cout << m_mother_name.c_str() << "_KFParticle_Container - Fatal Error - "
0421               << "unable to find DST node "
0422               << "G4_QA" << std::endl;
0423     assert(m_kfpContainer);
0424   }
0425   return Fun4AllReturnCodes::EVENT_OK;
0426 }
0427 
0428 std::string QAG4SimulationKFParticle::get_histo_prefix()
0429 {
0430   return std::string("h_") + Name() + std::string("_") + m_trackMapName + std::string("_");
0431 }