Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2026-07-16 08:11:27

0001 #include "../corrections/GeoAcceptanceCorrection.h"
0002 
0003 std::string combine_name(std::string base, std::string suffix)
0004 {
0005   if(suffix!="")
0006   {
0007     return base+"_"+suffix;
0008   }
0009   else
0010   {
0011     return base;
0012   }
0013 }
0014 
0015 std::string combine_title(std::string base, std::string suffix, std::string axislabel)
0016 {
0017   if(suffix!="")
0018   {
0019     return base+" "+suffix+";"+axislabel;
0020   }
0021   else
0022   {
0023     return base+";"+axislabel;
0024   }
0025 }
0026 
0027 struct HistContainer
0028 {
0029   TH1F* lifetime_truth;
0030   TH1F* lifetime_reco;
0031 
0032   TH1F* decaylength_truth;
0033   TH1F* decaylength_reco;
0034 
0035   TH1F* lifetime_truth_signal;
0036   TH1F* lifetime_truth_background;
0037   TH1F* lifetime_reco_signal;
0038   TH1F* lifetime_reco_background;
0039 
0040   HistContainer(std::string name_suffix, std::string title_suffix,
0041                 int nBins_t, float min_t, float max_t,
0042                 int nBins_L, float min_L, float max_L)
0043   {
0044     const std::string lifetime_label = "#tau [ps]";
0045     const std::string decaylength_label = "decay length [cm]";
0046 
0047     lifetime_truth = new TH1F(combine_name("lifetime_truth",name_suffix).c_str(),
0048                               combine_title("Truth lifetime",title_suffix,lifetime_label).c_str(),
0049                               nBins_t,min_t,max_t);
0050     lifetime_reco = new TH1F(combine_name("lifetime_reco",name_suffix).c_str(),
0051                              combine_title("Reco lifetime",title_suffix,lifetime_label).c_str(),
0052                              nBins_t,min_t,max_t);
0053     decaylength_truth = new TH1F(combine_name("decaylength_truth",name_suffix).c_str(),
0054                                  combine_title("Truth decay length",title_suffix,decaylength_label).c_str(),
0055                                  nBins_L,min_L,max_L);
0056     decaylength_reco = new TH1F(combine_name("decaylength_reco",name_suffix).c_str(),
0057                                 combine_title("Reco decay length",title_suffix,decaylength_label).c_str(),
0058                                 nBins_L,min_L,max_L);
0059     lifetime_truth_signal = new TH1F(combine_name("lifetime_truth_signal",name_suffix).c_str(),
0060                                      combine_title("Signal truth lifetime",title_suffix,lifetime_label).c_str(),
0061                                      nBins_t,min_t,max_t);
0062     lifetime_truth_background = new TH1F(combine_name("lifetime_truth_background",name_suffix).c_str(),
0063                                          combine_title("Background truth lifetime",title_suffix,lifetime_label).c_str(),
0064                                          nBins_t,min_t,max_t);
0065     lifetime_reco_signal = new TH1F(combine_name("lifetime_reco_signal",name_suffix).c_str(),
0066                                      combine_title("Signal reco lifetime",title_suffix,lifetime_label).c_str(),
0067                                      nBins_t,min_t,max_t);
0068     lifetime_reco_background = new TH1F(combine_name("lifetime_reco_background",name_suffix).c_str(),
0069                                          combine_title("Background reco lifetime",title_suffix,lifetime_label).c_str(),
0070                                          nBins_t,min_t,max_t);
0071   }
0072 
0073   void Write()
0074   {
0075     lifetime_truth->Write();
0076     lifetime_reco->Write();
0077     decaylength_truth->Write();
0078     decaylength_reco->Write();
0079     lifetime_truth_signal->Write();
0080     lifetime_truth_background->Write();
0081     lifetime_reco_signal->Write();
0082     lifetime_reco_background->Write();
0083   }
0084 };
0085 
0086 void KFParticle_truth_lifetime()
0087 {
0088   const bool verbose = false;
0089   const float min_DIRA = 0.99;
0090   const float min_track_IPxy = 0.05;
0091   const float min_decayLength = 0.05;
0092   const float min_mother_pt = 0.8;
0093   const int min_nMVTX = 1;
0094   const int min_nINTT = 1;
0095   const int min_nTPC = 1;
0096   const float max_pv_quality = 20.;
0097   const float max_daughter_DCA = 0.5;
0098 
0099   const std::string particle_name = "Lambda0";
0100   const int mother_pdgid = 3122;
0101   const float mother_mass = 1.115;
0102 
0103   const float speed = 2.99792458e-2;
0104 
0105   GeoAcceptanceCorrection geoacc_corr("/sphenix/u/cdean/analysis/LightFlavorRatios/geometric_acceptance/analysis/plots/Lambda0_geometric_acceptance_ratio_pT.root","Lambda0_inGeo_pT");
0106 
0107   //kshort file: /gpfs/mnt/gpfs02/sphenix/user/cdean/software/analysis/LightFlavorRatios/geometric_acceptance/simulation/outputKFParticle_Kshort_reco.root
0108   TFile* f = TFile::Open("/sphenix/tg/tg01/hf/mjpeters/LightFlavorResults/outputKFParticle_Lambda_reco_swum_weighted.root");
0109   TTree* t = (TTree*)f->Get("DecayTree");
0110 
0111   TFile* fout = new TFile("KFParticle_truth_h.root","RECREATE");
0112 
0113   const int nBins_lifetime = 100;
0114   const float min_lifetime = 0.;
0115   const float max_lifetime = 500.;
0116 
0117   const int nBins_decaylength = 100;
0118   const float min_decaylength = 0.;
0119   const float max_decaylength = 10.;
0120 
0121   // starting distributions
0122   HistContainer h("","",
0123                   nBins_lifetime,min_lifetime,max_lifetime,nBins_decaylength,min_decaylength,max_decaylength);
0124   // applying mother pt cut
0125   HistContainer h_motherpt("motherptcut","with mother pT>800MeV",
0126                            nBins_lifetime,min_lifetime,max_lifetime,nBins_decaylength,min_decaylength,max_decaylength);
0127   // applying acceptance corrections
0128   HistContainer h_geoacc("geoacc","with mother pT>800MeV, geo. acc. corrected",
0129                          nBins_lifetime,min_lifetime,max_lifetime,nBins_decaylength,min_decaylength,max_decaylength);
0130   // applying KFParticle candidate selections
0131   HistContainer h_kfcut("kfcut","with mother pT>800MeV, geo. acc. corrected, with KFParticle selection cuts",
0132                          nBins_lifetime,min_lifetime,max_lifetime,nBins_decaylength,min_decaylength,max_decaylength);
0133   // applying swimming corrections
0134   HistContainer h_swim("swim","with mother pT>800 MeV, geo. acc. corrected, with KFParticle selection cuts and swimming correction",
0135                        nBins_lifetime,min_lifetime,max_lifetime,nBins_decaylength,min_decaylength,max_decaylength);
0136 
0137   TH1F* lifetime_diff = new TH1F("lifetime_diff","lifetime_diff",100,-20.,20.);
0138   TH1F* decaylength_diff = new TH1F("decaylength_diff","decaylength_diff",100,-2.,2.);
0139 
0140   float decayTime;
0141   float decayLength;
0142   float mother_p;
0143   float mother_pt;
0144   float mother_DIRA;
0145   float mother_PV_x;
0146   float mother_PV_y;
0147   float mother_PV_z;
0148 
0149   std::vector<int>* track1_pdgid_history = nullptr;
0150   float track1_EV_x;
0151   float track1_EV_y;
0152   float track1_EV_z;
0153   float track1_PV_x;
0154   float track1_PV_y;
0155   float track1_PV_z;
0156   float track1_gpx;
0157   float track1_gpy;
0158   float track1_gpz;
0159   float track1_IP_xy;
0160   unsigned int track1_nMVTX;
0161   unsigned int track1_nINTT;
0162   unsigned int track1_nTPC;
0163 
0164   std::vector<int>* track2_pdgid_history = nullptr;
0165   float track2_EV_x;
0166   float track2_EV_y;
0167   float track2_EV_z;
0168   float track2_PV_x;
0169   float track2_PV_y;
0170   float track2_PV_z;
0171   float track2_gpx;
0172   float track2_gpy;
0173   float track2_gpz;
0174   float track2_IP_xy;
0175   unsigned int track2_nMVTX;
0176   unsigned int track2_nINTT;
0177   unsigned int track2_nTPC;
0178 
0179   float pv_chi2;
0180   unsigned int pv_ndof;
0181   float daughter_DCA;
0182 
0183   std::vector<float>* turningPoints_TAU = nullptr;
0184   float swim_weight;
0185 
0186   t->SetBranchAddress((particle_name+"_decayTime").c_str(),&decayTime);
0187   t->SetBranchAddress((particle_name+"_decayLength").c_str(),&decayLength);
0188   t->SetBranchAddress((particle_name+"_p").c_str(),&mother_p);
0189   t->SetBranchAddress((particle_name+"_pT").c_str(),&mother_pt);
0190   t->SetBranchAddress((particle_name+"_DIRA").c_str(),&mother_DIRA);
0191   t->SetBranchAddress("primary_vertex_x",&mother_PV_x);
0192   t->SetBranchAddress("primary_vertex_y",&mother_PV_y);
0193   t->SetBranchAddress("primary_vertex_z",&mother_PV_z);
0194 
0195   t->SetBranchAddress("track_1_true_track_history_PDG_ID",&track1_pdgid_history);
0196   t->SetBranchAddress("track_1_true_EV_x",&track1_EV_x);
0197   t->SetBranchAddress("track_1_true_EV_y",&track1_EV_y);
0198   t->SetBranchAddress("track_1_true_EV_z",&track1_EV_z);
0199   t->SetBranchAddress("track_1_true_PV_x",&track1_PV_x);
0200   t->SetBranchAddress("track_1_true_PV_y",&track1_PV_y);
0201   t->SetBranchAddress("track_1_true_PV_z",&track1_PV_z);
0202   t->SetBranchAddress("track_1_true_px",&track1_gpx);
0203   t->SetBranchAddress("track_1_true_py",&track1_gpy);
0204   t->SetBranchAddress("track_1_true_pz",&track1_gpz);
0205   t->SetBranchAddress("track_1_IP_xy",&track1_IP_xy);
0206   t->SetBranchAddress("track_1_MVTX_nHits",&track1_nMVTX);
0207   t->SetBranchAddress("track_1_INTT_nHits",&track1_nINTT);
0208   t->SetBranchAddress("track_1_TPC_nHits",&track1_nTPC);
0209 
0210   t->SetBranchAddress("track_2_true_track_history_PDG_ID",&track2_pdgid_history);
0211   t->SetBranchAddress("track_2_true_EV_x",&track2_EV_x);
0212   t->SetBranchAddress("track_2_true_EV_y",&track2_EV_y);
0213   t->SetBranchAddress("track_2_true_EV_z",&track2_EV_z);
0214   t->SetBranchAddress("track_2_true_PV_x",&track2_PV_x);
0215   t->SetBranchAddress("track_2_true_PV_y",&track2_PV_y);
0216   t->SetBranchAddress("track_2_true_PV_z",&track2_PV_z);
0217   t->SetBranchAddress("track_2_true_px",&track2_gpx);
0218   t->SetBranchAddress("track_2_true_py",&track2_gpy);
0219   t->SetBranchAddress("track_2_true_pz",&track2_gpz);
0220   t->SetBranchAddress("track_2_IP_xy",&track2_IP_xy);
0221   t->SetBranchAddress("track_2_MVTX_nHits",&track2_nMVTX);
0222   t->SetBranchAddress("track_2_INTT_nHits",&track2_nINTT);
0223   t->SetBranchAddress("track_2_TPC_nHits",&track2_nTPC);
0224 
0225   t->SetBranchAddress("primary_vertex_chi2",&pv_chi2);
0226   t->SetBranchAddress("primary_vertex_ndof",&pv_ndof);
0227   t->SetBranchAddress("track_1_track_2_DCA",&daughter_DCA);
0228 
0229   t->SetBranchAddress("swim_weight",&swim_weight);
0230   t->SetBranchAddress("turningPoints_TAU",&turningPoints_TAU);
0231 
0232   for(int i=0;i<t->GetEntries();i++)
0233   {
0234     if(i % 1000 == 0) std::cout << i << std::endl;
0235     t->GetEntry(i);
0236 
0237     if(track1_nMVTX<min_nMVTX || track2_nMVTX<min_nMVTX ||
0238        track1_nINTT<min_nINTT || track2_nINTT<min_nINTT ||
0239        track1_nTPC<min_nTPC || track2_nTPC<min_nTPC ||
0240        pv_chi2/pv_ndof>max_pv_quality ||
0241        daughter_DCA>max_daughter_DCA)
0242     {
0243       continue;
0244     }
0245 
0246     if(verbose)
0247     {
0248       std::cout << "--------------------------------------------" << std::endl;
0249       std::cout << "entry " << i << std::endl;
0250       std::cout << "reco decayLength: " << decayLength << " decayTime: " << decayTime << std::endl;
0251       std::cout << "p: " << mother_p << std::endl;
0252       std::cout << "reco PV: (" << mother_PV_x << ", " << mother_PV_y << ", " << mother_PV_z << ")" << std::endl;
0253     }
0254 
0255     const bool is_signal = (track1_pdgid_history && track2_pdgid_history &&
0256                             track1_pdgid_history->size()>0 && track2_pdgid_history->size()>0 && 
0257                             ((track1_pdgid_history->at(0)==mother_pdgid && track2_pdgid_history->at(0)==mother_pdgid) || 
0258                              (track1_pdgid_history->at(0)==-mother_pdgid && track2_pdgid_history->at(0)==-mother_pdgid)));
0259 
0260     if(verbose)
0261     {
0262       if(is_signal)
0263       {
0264         std::cout << "is signal" << std::endl;
0265       }
0266       else
0267       {
0268         std::cout << "is not signal" << std::endl;
0269         if(track1_pdgid_history == nullptr)
0270         {
0271           std::cout << "history unavailable for track 1" << std::endl;
0272         }
0273         if(track2_pdgid_history == nullptr)
0274         {
0275           std::cout << "history unavailable for track 2" << std::endl;
0276         }
0277         if(track1_pdgid_history && track2_pdgid_history && track1_pdgid_history->size()==0)
0278         {
0279           std::cout << "history size is zero for track 1" << std::endl;
0280         }
0281         if(track1_pdgid_history && track2_pdgid_history && track2_pdgid_history->size()==0)
0282         {
0283           std::cout << "history size is zero for track 2" << std::endl;
0284         }
0285         if(track1_pdgid_history && track2_pdgid_history && track1_pdgid_history->size()>0 && track2_pdgid_history->size()>0)
0286         {
0287           std::cout << "direct descendant PIDs are " << track1_pdgid_history->at(0) << " and " << track2_pdgid_history->at(0) << std::endl;
0288         }
0289       }
0290     }
0291 
0292     std::array<float,3> true_SV;
0293 
0294     if(fabs(track1_PV_x+99.)>0.001)
0295     {
0296       true_SV = {track1_PV_x, track1_PV_y, track1_PV_z};
0297     }
0298     else if(fabs(track2_PV_x+99.)>0.001)
0299     {
0300       true_SV = {track2_PV_x, track2_PV_y, track2_PV_z};
0301     }
0302     else
0303     {
0304       true_SV = {track1_EV_x,track1_EV_y,track1_EV_z};
0305     }
0306 
0307     if(verbose)
0308     {
0309       std::cout << "SV: (" << true_SV[0] << ", " << true_SV[1] << ", " << true_SV[2] << ")" << std::endl;
0310       std::cout << "PV: (" << mother_PV_x << ", " << mother_PV_y << ", " << mother_PV_z << ")" << std::endl;
0311     }
0312 
0313     const float true_decayLength = sqrt(pow(true_SV[0]-mother_PV_x,2)+pow(true_SV[1]-mother_PV_y,2)+pow(true_SV[2]-mother_PV_z,2));
0314     const float true_p = sqrt(pow(track1_gpx+track2_gpx,2)+pow(track1_gpy+track2_gpy,2)+pow(track1_gpz+track2_gpz,2));
0315     const float true_decayTime = 1./speed * mother_mass*true_decayLength/true_p;
0316 
0317     if(verbose)
0318     {
0319       std::cout << "true decay length: " << true_decayLength << std::endl;
0320       std::cout << "true p: " << true_p << std::endl;
0321       std::cout << "true decay time: " << true_decayTime << std::endl;
0322     }
0323 
0324     h.lifetime_reco->Fill(decayTime);
0325     h.decaylength_reco->Fill(decayLength);
0326     h.decaylength_truth->Fill(true_decayLength);
0327     decaylength_diff->Fill(decayLength-true_decayLength);
0328     h.lifetime_truth->Fill(true_decayTime);
0329     lifetime_diff->Fill(decayTime-true_decayTime);
0330 
0331     if(is_signal)
0332     {
0333       h.lifetime_truth_signal->Fill(true_decayTime);
0334       h.lifetime_reco_signal->Fill(decayTime);
0335     }
0336     else
0337     {
0338       h.lifetime_truth_background->Fill(true_decayTime);
0339       h.lifetime_reco_background->Fill(decayTime);
0340     }
0341 
0342     if(mother_pt>min_mother_pt)
0343     {
0344       h_motherpt.lifetime_truth->Fill(true_decayTime);
0345       h_motherpt.decaylength_truth->Fill(true_decayLength);
0346       h_motherpt.lifetime_reco->Fill(decayTime);
0347       h_motherpt.decaylength_reco->Fill(decayLength);
0348 
0349       const float geoacc_weight = 1./geoacc_corr.h_corr->Interpolate(mother_pt);
0350       h_geoacc.lifetime_truth->Fill(true_decayTime,geoacc_weight);
0351       h_geoacc.decaylength_truth->Fill(true_decayLength,geoacc_weight);
0352       h_geoacc.lifetime_reco->Fill(decayTime,geoacc_weight);
0353       h_geoacc.decaylength_reco->Fill(decayLength,geoacc_weight);
0354 
0355       if(is_signal)
0356       {
0357         h_motherpt.lifetime_truth_signal->Fill(true_decayTime);
0358         h_motherpt.lifetime_reco_signal->Fill(decayTime);
0359 
0360         h_geoacc.lifetime_truth_signal->Fill(true_decayTime,geoacc_weight);
0361         h_geoacc.lifetime_reco_signal->Fill(decayTime,geoacc_weight);
0362       }
0363       else
0364       {
0365         h_motherpt.lifetime_truth_background->Fill(true_decayTime);
0366         h_motherpt.lifetime_reco_background->Fill(decayTime);
0367 
0368         h_geoacc.lifetime_truth_background->Fill(true_decayTime,geoacc_weight);
0369         h_geoacc.lifetime_reco_background->Fill(decayTime,geoacc_weight);
0370       }
0371 
0372       if(mother_DIRA>min_DIRA && decayLength>min_decayLength && fabs(track1_IP_xy)>min_track_IPxy && fabs(track2_IP_xy)>min_track_IPxy)
0373       {
0374         h_kfcut.lifetime_truth->Fill(true_decayTime,geoacc_weight);
0375         h_kfcut.decaylength_truth->Fill(true_decayLength,geoacc_weight);
0376         h_kfcut.lifetime_reco->Fill(decayTime,geoacc_weight);
0377         h_kfcut.decaylength_reco->Fill(decayLength,geoacc_weight);
0378 
0379         h_swim.lifetime_truth->Fill(true_decayTime,geoacc_weight*swim_weight);
0380         h_swim.decaylength_truth->Fill(true_decayLength,geoacc_weight*swim_weight);
0381         h_swim.lifetime_reco->Fill(decayTime,geoacc_weight*swim_weight);
0382         h_swim.decaylength_reco->Fill(decayLength,geoacc_weight*swim_weight);
0383 
0384         if(is_signal)
0385         {
0386           h_kfcut.lifetime_truth_signal->Fill(true_decayTime,geoacc_weight);
0387           h_kfcut.lifetime_reco_signal->Fill(decayTime,geoacc_weight);
0388 
0389           h_swim.lifetime_truth_signal->Fill(true_decayTime,geoacc_weight*swim_weight);
0390           h_swim.lifetime_reco_signal->Fill(decayTime,geoacc_weight*swim_weight);
0391         }
0392         else
0393         {
0394           h_kfcut.lifetime_truth_background->Fill(true_decayTime,geoacc_weight);
0395           h_kfcut.lifetime_reco_background->Fill(decayTime,geoacc_weight);
0396 
0397           h_swim.lifetime_truth_background->Fill(true_decayTime,geoacc_weight*swim_weight);
0398           h_swim.lifetime_reco_background->Fill(decayTime,geoacc_weight*swim_weight);
0399         }
0400       }
0401     }
0402   }
0403 
0404   h.Write();
0405   h_motherpt.Write();
0406   h_geoacc.Write();
0407   h_kfcut.Write();
0408   h_swim.Write();
0409 
0410   lifetime_diff->Write();
0411   decaylength_diff->Write();
0412 }