Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:18:09

0001 #include "SiliconSeedsAna.h"
0002 
0003 #include <ffarawobjects/Gl1Packet.h>
0004 #include <ffaobjects/EventHeader.h>
0005 #include <trackbase/InttDefs.h>
0006 
0007 #include <qautils/QAHistManagerDef.h>
0008 #include <qautils/QAUtil.h>
0009 
0010 #include <phool/PHCompositeNode.h>
0011 #include <phool/getClass.h>
0012 #include <qautils/QAHistManagerDef.h>
0013 
0014 #include <TH2.h>
0015 #include <TProfile.h>
0016 #include <TProfile2D.h>
0017 
0018 #include <TFile.h>
0019 #include <TTree.h>
0020 
0021 // Add member variables for TTree and track data
0022 
0023 //____________________________________________________________________________..
0024 SiliconSeedsAna::SiliconSeedsAna(const std::string &name)
0025     : SubsysReco(name)
0026 {
0027 }
0028 
0029 #define LOG(msg) std::cout << "[SiliconSeedsAna] " << msg << std::endl;
0030 
0031 void SiliconSeedsAna::clearTrackVectors() {
0032   track_id.clear(); 
0033   track_x.clear(); track_y.clear(); track_z.clear();
0034   track_px.clear(); track_py.clear(); track_pz.clear();
0035   track_eta.clear(); track_phi.clear(); track_pt.clear();
0036   track_chi2ndf.clear(); track_charge.clear(); track_crossing.clear();
0037   track_nmaps.clear(); track_nintt.clear(); track_innerintt.clear(); track_outerintt.clear();
0038   track_x_emc.clear(); track_y_emc.clear(); track_z_emc.clear();
0039   track_x_oemc.clear(); track_y_oemc.clear(); track_z_oemc.clear();
0040   track_px_emc.clear(); track_py_emc.clear(); track_pz_emc.clear();
0041   track_eta_emc.clear(); track_phi_emc.clear(); track_pt_emc.clear();
0042 
0043   // Clear matched calo vectors
0044   matched_calo_x.clear();
0045   matched_calo_y.clear();
0046   matched_calo_z.clear();
0047   matched_calo_r.clear();
0048   matched_calo_phi.clear();
0049   matched_calo_eta.clear();
0050   matched_calo_energy.clear();
0051   matched_calo_dR.clear();
0052 }
0053 
0054 void SiliconSeedsAna::clearCaloVectors() {
0055   calo_x.clear();
0056   calo_y.clear();
0057   calo_z.clear();
0058   calo_r.clear();
0059   calo_phi.clear();
0060   calo_eta.clear();
0061   calo_energy.clear();
0062   calo_chi2.clear();
0063   calo_prob.clear();
0064 }
0065 
0066 void SiliconSeedsAna::fillEMCalState(SvtxTrackState* state, SvtxTrackState* ostate) {
0067   track_x_emc.push_back(  state ? state->get_x()  : NAN);
0068   track_y_emc.push_back(  state ? state->get_y()  : NAN);
0069   track_z_emc.push_back(  state ? state->get_z()  : NAN);
0070   track_px_emc.push_back( state ? state->get_px() : NAN);
0071   track_py_emc.push_back( state ? state->get_py() : NAN);
0072   track_pz_emc.push_back( state ? state->get_pz() : NAN);
0073   track_eta_emc.push_back(state ? state->get_eta(): NAN);
0074   track_phi_emc.push_back(state ? state->get_phi(): NAN);
0075   track_pt_emc.push_back( state ? state->get_pt() : NAN);
0076   track_x_oemc.push_back(ostate ? ostate->get_x()  : NAN);
0077   track_y_oemc.push_back(ostate ? ostate->get_y()  : NAN);
0078   track_z_oemc.push_back(ostate ? ostate->get_z()  : NAN);
0079 
0080 
0081   // --- EMCal cluster matching ---
0082   // Find the closest EMCal cluster in eta/phi to this state
0083   float best_dR = 9999.0;
0084   int best_idx = -1;
0085   float state_eta = state ? state->get_eta() : NAN;
0086   float state_phi = state ? state->get_phi() : NAN;
0087   // Use calo_eta/calo_phi/calo_x/etc. as the cluster list
0088   for (size_t icl = 0; icl < calo_eta.size(); ++icl) {
0089     float deta = state_eta - calo_eta[icl];
0090     float dphi = state_phi - calo_phi[icl];
0091     // Wrap dphi into [-pi, pi]
0092     while (dphi > M_PI) dphi -= 2 * M_PI;
0093     while (dphi < -M_PI) dphi += 2 * M_PI;
0094     float dR = std::sqrt(deta * deta + dphi * dphi);
0095     if (dR < best_dR) {
0096       best_dR = dR;
0097       best_idx = icl;
0098     }
0099   }
0100   if (best_idx >= 0) {
0101     matched_calo_x.push_back(calo_x[best_idx]);
0102     matched_calo_y.push_back(calo_y[best_idx]);
0103     matched_calo_z.push_back(calo_z[best_idx]);
0104     matched_calo_r.push_back(calo_r[best_idx]);
0105     matched_calo_phi.push_back(calo_phi[best_idx]);
0106     matched_calo_eta.push_back(calo_eta[best_idx]);
0107     matched_calo_energy.push_back(calo_energy[best_idx]);
0108     matched_calo_dR.push_back(best_dR);
0109   } else {
0110     matched_calo_x.push_back(NAN);
0111     matched_calo_y.push_back(NAN);
0112     matched_calo_z.push_back(NAN);
0113     matched_calo_r.push_back(NAN);
0114     matched_calo_phi.push_back(NAN);
0115     matched_calo_eta.push_back(NAN);
0116     matched_calo_energy.push_back(NAN);
0117     matched_calo_dR.push_back(NAN);
0118   }
0119 }
0120 
0121 void SiliconSeedsAna::initTrackTreeBranches() {
0122   trackTree = new TTree("trackTree", "Track Data");
0123   trackTree->Branch("evt", &evt, "evt/I");
0124   trackTree->Branch("track_id", &track_id);
0125   trackTree->Branch("x0", &track_x);
0126   trackTree->Branch("y0", &track_y);
0127   trackTree->Branch("z0", &track_z);
0128   trackTree->Branch("px0", &track_px);
0129   trackTree->Branch("py0", &track_py);
0130   trackTree->Branch("pz0", &track_pz);
0131   trackTree->Branch("eta0", &track_eta);
0132   trackTree->Branch("phi0", &track_phi);
0133   trackTree->Branch("pt0", &track_pt);
0134   trackTree->Branch("chi2ndf", &track_chi2ndf);
0135   trackTree->Branch("charge", &track_charge);
0136   trackTree->Branch("nmaps", &track_nmaps);
0137   trackTree->Branch("nintt", &track_nintt);
0138   trackTree->Branch("innerintt", &track_innerintt);
0139   trackTree->Branch("outerintt", &track_outerintt);
0140   trackTree->Branch("crossing", &track_crossing);
0141   trackTree->Branch("x_proj_emc", &track_x_emc);
0142   trackTree->Branch("y_proj_emc", &track_y_emc);
0143   trackTree->Branch("z_proj_emc", &track_z_emc);
0144   trackTree->Branch("px_proj_emc", &track_px_emc);
0145   trackTree->Branch("py_proj_emc", &track_py_emc);
0146   trackTree->Branch("pz_proj_emc", &track_pz_emc);
0147   trackTree->Branch("eta_proj_emc", &track_eta_emc);
0148   trackTree->Branch("phi_proj_emc", &track_phi_emc);
0149   trackTree->Branch("pt_proj_emc", &track_pt_emc);
0150   // Add matched EMCal cluster branches
0151   trackTree->Branch("matched_calo_x", &matched_calo_x);
0152   trackTree->Branch("matched_calo_y", &matched_calo_y);
0153   trackTree->Branch("matched_calo_z", &matched_calo_z);
0154   trackTree->Branch("matched_calo_r", &matched_calo_r);
0155   trackTree->Branch("matched_calo_phi", &matched_calo_phi);
0156   trackTree->Branch("matched_calo_eta", &matched_calo_eta);
0157   trackTree->Branch("matched_calo_energy", &matched_calo_energy);
0158   trackTree->Branch("matched_calo_dR", &matched_calo_dR);
0159   trackTree->SetBasketSize("*", 50000);
0160 }
0161 
0162 void SiliconSeedsAna::initCaloTreeBranches() {
0163   caloTree = new TTree("caloTree", "Calo Data");
0164   caloTree->Branch("calo_evt", &calo_evt, "calo_evt/I");
0165   caloTree->Branch("x",     &calo_x);
0166   caloTree->Branch("y",     &calo_y);
0167   caloTree->Branch("z",     &calo_z);
0168   caloTree->Branch("r",     &calo_r);
0169   caloTree->Branch("phi",   &calo_phi);
0170   caloTree->Branch("eta",   &calo_eta);
0171   caloTree->Branch("energy",&calo_energy);
0172   caloTree->Branch("chi2",  &calo_chi2);
0173   caloTree->Branch("prob",  &calo_prob);
0174   caloTree->SetBasketSize("*",50000);
0175 }
0176 
0177 //____________________________________________________________________________..
0178 int SiliconSeedsAna::InitRun(PHCompositeNode * /*unused*/)
0179 {
0180   m_outfile = new TFile(m_outputfilename.c_str(), "RECREATE");
0181 
0182   createHistos();
0183   // Create a TTree to store track data and initialize branches
0184   initTrackTreeBranches();
0185   SiClusTree = new TTree("SiClusTree", "Silicon Cluster Data");
0186   SiClusTree->Branch("evt", &evt, "evt/I");
0187   SiClusTree->Branch("Siclus_trackid", &SiClus_trackid);
0188   SiClusTree->Branch("Siclus_layer", &SiClus_layer);
0189   SiClusTree->Branch("Siclus_x", &SiClus_x);
0190   SiClusTree->Branch("Siclus_y", &SiClus_y);
0191   SiClusTree->Branch("Siclus_z", &SiClus_z);
0192   SiClusTree->Branch("Siclus_t", &SiClus_t);
0193   SiClusTree->SetBasketSize("*",50000); // Set a larger basket size for better performance
0194 
0195   SiClusAllTree = new TTree("SiClusAllTree", "Silicon Cluster Data");
0196   SiClusAllTree->Branch("evt", &evt, "evt/I");
0197   SiClusAllTree->Branch("Siclus_trackid", &SiClus_trackid);
0198   SiClusAllTree->Branch("Siclus_layer", &SiClus_layer);
0199   SiClusAllTree->Branch("Siclus_x", &SiClus_x);
0200   SiClusAllTree->Branch("Siclus_y", &SiClus_y);
0201   SiClusAllTree->Branch("Siclus_z", &SiClus_z);
0202   SiClusAllTree->Branch("Siclus_t", &SiClus_t);
0203   SiClusAllTree->SetBasketSize("*",50000); // Set a larger basket size for better performance
0204 
0205   initCaloTreeBranches();
0206 
0207   evtTree = new TTree("evtTree", "Event Data");
0208   evtTree->Branch("evt",     &evt,       "evt/I");
0209   evtTree->Branch("caloevt", &calo_evt,  "caloevt/I");
0210   evtTree->Branch("bco",     &evt_bco,   "bco/l");
0211   evtTree->Branch("crossing",&evt_crossing, "crossing/I");
0212   evtTree->Branch("nintt",   &evt_nintt, "nintt/I");
0213   evtTree->Branch("nintt50", &evt_nintt50,"nintt50/I");
0214   evtTree->Branch("nmaps",   &evt_nmaps, "nmaps/I");
0215   evtTree->Branch("nemc",    &evt_nemc,  "nemc/I");
0216   evtTree->Branch("nemc02",  &evt_nemc02,"nemc02/I");
0217   evtTree->Branch("nsiseed", &evt_nsiseed, "nsiseed/I");
0218   evtTree->Branch("nsiseed0",&evt_nsiseed0,"nsiseed0/I");
0219   evtTree->Branch("xvtx",    &evt_xvtx,  "xvtx/F");
0220   evtTree->Branch("yvtx",    &evt_yvtx,  "yvtx/F");
0221   evtTree->Branch("zvtx",    &evt_zvtx,  "zvtx/F");
0222 
0223   // Truth tree and branches
0224   if(isMC){
0225     truthTree = new TTree("truthTree", "Truth Particle Data");
0226     truthTree->Branch("truth_pid",   &truth_pid);
0227     truthTree->Branch("truth_px",    &truth_px);
0228     truthTree->Branch("truth_py",    &truth_py);
0229     truthTree->Branch("truth_pz",    &truth_pz);
0230     truthTree->Branch("truth_e",     &truth_e);
0231     truthTree->Branch("truth_pt",    &truth_pt);
0232     truthTree->Branch("truth_eta",   &truth_eta);
0233     truthTree->Branch("truth_phi",   &truth_phi);
0234     truthTree->Branch("truth_vtxid", &truth_vtxid);
0235     truthTree->Branch("truth_vtx_x", &truth_vtx_x);
0236     truthTree->Branch("truth_vtx_y", &truth_vtx_y);
0237     truthTree->Branch("truth_vtx_z", &truth_vtx_z);
0238     truthTree->SetBasketSize("*",50000); // Set a larger basket size for better performance
0239   }
0240 
0241   return Fun4AllReturnCodes::EVENT_OK;
0242 }
0243 
0244 //____________________________________________________________________________..
0245 int SiliconSeedsAna::process_event(PHCompositeNode* topNode)
0246 {
0247   if(isMC)
0248     fillTruthTree(topNode);
0249 
0250   processCaloClusters(topNode);
0251   processTrackMap(topNode);
0252   processSiCluster(topNode);
0253   processVertexMap(topNode);
0254 
0255   //////////////
0256   {
0257     // reset in processTrackMap : evt_nsiseed=evt_nsiseed0=0;
0258     // reset in processSiCluster :  evt_nintt = evt_nintt50 = evt_nmaps = 0;
0259     evt_bco = 0;
0260     evt_crossing = std::numeric_limits<int>::signaling_NaN();
0261 
0262     auto gl1        = findNode::getClass<Gl1Packet>(  topNode, "GL1Packet");
0263     auto evthdr     = findNode::getClass<EventHeader>(topNode, "EventHeader");
0264     //auto clustermap = findNode::getClass<TrkrClusterContainer>(topNode, m_clusterContainerName);
0265 
0266     if(gl1){
0267       uint64_t bunch_gl1= gl1->getBunchNumber();
0268       std::cout<<"BCO : "<<bunch_gl1<<", ";
0269       evt_bco =  bunch_gl1;
0270 
0271     }
0272     else { std::cout<<"No GL1Packet"<<std::endl; }
0273     if(evthdr){
0274       uint64_t bunch_evt= evthdr->get_BunchCrossing();
0275       std::cout<<"Evt Header : "<<bunch_evt;
0276       //  evt_bco = 
0277 
0278     }
0279     else { std::cout<<"No EventHeader"<<std::endl; }
0280     std::cout<<std::endl;
0281 
0282 /*
0283     if(clustermap){
0284       int nclus_intt[2]={0,0};
0285       int nclus_intt50[2]={0,0};
0286       for (auto layer = 0; layer < 4; layer++)
0287       {
0288         int inout = (layer/2);
0289         for (const auto &hitsetkey : clustermap->getHitSetKeys(TrkrDefs::TrkrId::inttId, layer + 3))
0290         {
0291           auto range = clustermap->getClusters(hitsetkey);
0292 
0293           int intt_time = InttDefs::getTimeBucketId(hitsetkey);
0294           //--int intt_ldr  = InttDefs::getLadderPhiId(hitsetkey);
0295           for (auto clusIter = range.first; clusIter != range.second; ++clusIter)
0296           {
0297             //const auto ckey = citer->first;
0298             //int time = InttDef::getTimeBucket(ckey);
0299             if(intt_time==0){
0300               nclus_intt[inout]++;
0301             }
0302             if(0<=intt_time&&intt_time<50){
0303               nclus_intt50[inout]++;
0304             }
0305           }
0306           //      std::cout<<"nintt time : "<<layer<<" "<<intt_ldr<<" : "<<intt_time<<" "<<nclus_intt[inout]<<std::endl;
0307         }
0308       }
0309       evt_nintt   = (nclus_intt[0] + nclus_intt[1]);
0310       evt_nintt50 = (nclus_intt50[0] + nclus_intt50[1]);
0311       std::cout<<"nintt "<<evt_nintt<<" "<<evt_nintt50<<std::endl;
0312 
0313       //std::set<TrkrDefs::TrkrId> detectors;
0314       //detectors.insert(TrkrDefs::TrkrId::mvtxId);
0315       int nclusmvtx[3] = {0,0,0};
0316       //float ntpval_mvtx[20];
0317       //for (const auto &det : detectors)
0318       //{
0319         for (const auto &layer : {0, 1, 2})
0320         {
0321           for (const auto &hitsetkey : clustermap->getHitSetKeys(TrkrDefs::TrkrId::mvtxId, layer))
0322           {
0323             auto range = clustermap->getClusters(hitsetkey);
0324 
0325             int strbid   = MvtxDefs::getStrobeId(hitsetkey);
0326            //-- int mvtx_ldr  = MvtxDefs::getStaveId(hitsetkey);
0327             //int nmvtx = range.second - range.first;;
0328             if(strbid==0){
0329               for (auto citer = range.first; citer != range.second; ++citer)
0330               {
0331                 nclusmvtx[layer]++;
0332               }
0333             }
0334             //         std::cout<<"mvtx: "<<layer<<" "<<mvtx_ldr<<" : "<<strbid<<std::endl;
0335 
0336           }
0337 
0338           evt_nmaps+= nclusmvtx[layer];
0339           //std::cout<<"nmvtx "<<layer<<" "<<nclusmvtx[layer]<<" "<<evt_nmaps<<std::endl;
0340         }
0341         std::cout<<"nmvtx "<<evt_nmaps<<std::endl;
0342         //}
0343     }
0344 */
0345 
0346     evtTree->Fill();
0347   }
0348   //////////////
0349 
0350   return Fun4AllReturnCodes::EVENT_OK;
0351 }
0352 
0353 void SiliconSeedsAna::fillTruthTree(PHCompositeNode* topNode)
0354 {
0355   PHG4TruthInfoContainer* m_truth_info = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
0356   if (!m_truth_info)
0357   {
0358     std::cout << PHWHERE << "Warning: G4TruthInfo not found. Skipping truthTree filling for this event." << std::endl;
0359     return;
0360   }
0361   truth_pid.clear();
0362   truth_px.clear(); truth_py.clear(); truth_pz.clear(); truth_e.clear();
0363   truth_pt.clear(); truth_eta.clear(); truth_phi.clear();
0364   truth_vtxid.clear();
0365   truth_vtx_x.clear(); truth_vtx_y.clear(); truth_vtx_z.clear();
0366 
0367   const auto  vtxrng = m_truth_info->GetPrimaryVtxRange();
0368   for (auto viter = vtxrng.first; viter != vtxrng.second; ++viter)
0369   {
0370     auto Vtx = viter->second;
0371     truth_vtx_x.push_back(Vtx->get_x());
0372     truth_vtx_y.push_back(Vtx->get_y());
0373     truth_vtx_z.push_back(Vtx->get_z());
0374     std::cout<<" primVtxid: "<<viter->first<<", "<<Vtx->get_x()<<" "<<Vtx->get_y()<<" "<<Vtx->get_z()<<std::endl;
0375   }
0376 
0377   const auto prange = m_truth_info->GetPrimaryParticleRange();
0378   for (auto iter = prange.first; iter != prange.second; ++iter)
0379   {
0380     PHG4Particle* ptcl = iter->second;
0381     if (!ptcl) continue;
0382 
0383     int vtxid = ptcl->get_vtx_id();
0384     //auto primVtx = m_truth_info->GetPrimaryVtx(vtxid);
0385     //std::cout<<" vtxid: "<<vtxid<<", "<<primVtx->get_x()<<" "<<primVtx->get_y()<<" "<<primVtx->get_z()<<std::endl;
0386 
0387     TLorentzVector p(ptcl->get_px(), ptcl->get_py(), ptcl->get_pz(), ptcl->get_e());
0388 
0389     truth_pid.push_back(ptcl->get_pid());
0390     truth_px.push_back(ptcl->get_px());
0391     truth_py.push_back(ptcl->get_py());
0392     truth_pz.push_back(ptcl->get_pz());
0393     truth_e.push_back(ptcl->get_e());
0394     truth_pt.push_back(p.Pt());
0395     truth_eta.push_back(p.Eta());
0396     truth_phi.push_back(p.Phi());
0397     truth_vtxid.push_back(vtxid);
0398   }
0399   truthTree->Fill();
0400 }
0401 
0402 void SiliconSeedsAna::processTrackMap(PHCompositeNode* topNode)
0403 {
0404   evt_nsiseed=evt_nsiseed0=0;
0405 
0406   auto clustermap = findNode::getClass<TrkrClusterContainer>(topNode, m_clusterContainerName);
0407   auto geometry   = findNode::getClass<ActsGeometry>(topNode, m_actsgeometryName);
0408   auto vertexmap  = findNode::getClass<SvtxVertexMap>(topNode, m_vertexMapName);
0409 
0410   trackmap = findNode::getClass<SvtxTrackMap>(topNode, m_trackMapName);
0411   if (!trackmap)
0412   {
0413     std::cout << PHWHERE << "Missing trackmap, can't continue" << std::endl;
0414     return;
0415   }
0416   if (!clustermap)
0417   {
0418     std::cout << PHWHERE << "Missing clustermap, can't continue" << std::endl;
0419     return;
0420   }
0421   if (!geometry)
0422   {
0423     std::cout << PHWHERE << "Missing geometry, can't continue" << std::endl;
0424     return;
0425   }
0426   if (!vertexmap)
0427   {
0428     std::cout << PHWHERE << "Missing vertexmap, can't continue" << std::endl;
0429     return;
0430   }
0431 
0432   if((evt%1000)==0) std::cout << "start track map  EVENT " << evt << " is OK" << std::endl;
0433 
0434   evt_nsiseed=trackmap->size();
0435   h_ntrack1d->Fill(trackmap->size());
0436 
0437   std::pair<int, int> ntrack_isfromvtx;   // first: number of tracks associated to a vertex, second: number of tracks not associated to a vertex
0438   std::pair<int, int> ntrack_isposcharge; // first: number of tracks with negative charge, second: number of tracks with positive charge
0439 
0440   //--LOG("Start track map for EVENT " << evt);
0441   clearTrackVectors();
0442 
0443   SiClus_trackid.clear();
0444   SiClus_layer.clear();
0445   SiClus_x.clear();
0446   SiClus_y.clear();
0447   SiClus_z.clear();
0448   SiClus_t.clear();
0449 
0450   for (auto &iter : *trackmap)
0451   {
0452     track = iter.second;
0453     if (!track)
0454       continue;
0455 
0456     si_seed = track->get_silicon_seed();
0457     int trkcrossing = track->get_crossing();
0458     if (trkcrossing != 0 && !isMC)
0459       continue;
0460     int   t_id      = track->get_id();
0461     float t_eta     = track->get_eta();
0462     float t_phi     = track->get_phi();
0463     float t_pt      = track->get_pt();
0464     int   t_charge  = track->get_charge();
0465     float t_chi2ndf = track->get_quality();
0466     float t_x       = track->get_x();
0467     float t_y       = track->get_y();
0468     float t_z       = track->get_z();
0469     float t_px      = track->get_px();
0470     float t_py      = track->get_py();
0471     float t_pz      = track->get_pz();
0472     int t_crossing  = trkcrossing;
0473     if(t_crossing==0) evt_nsiseed0++;
0474 
0475     int t_nmaps = 0, t_nintt = 0, t_inner = 0, t_outer = 0;
0476 
0477     if (!si_seed)
0478     {
0479       track_nmaps.push_back(0);
0480       track_nintt.push_back(0);
0481       track_innerintt.push_back(0);
0482       track_outerintt.push_back(0);
0483     }
0484     else
0485     {
0486       for (auto key_iter = si_seed->begin_cluster_keys(); key_iter != si_seed->end_cluster_keys(); ++key_iter)
0487       {
0488         const auto &cluster_key = *key_iter;
0489         trkrCluster = clustermap->findCluster(cluster_key);
0490         if (!trkrCluster)
0491         {
0492           continue;
0493         }
0494         if (TrkrDefs::getTrkrId(cluster_key) == TrkrDefs::TrkrId::mvtxId)
0495         {
0496           t_nmaps++;
0497         }
0498         if (TrkrDefs::getTrkrId(cluster_key) == TrkrDefs::TrkrId::inttId)
0499         {
0500           t_nintt++;
0501         }
0502         Acts::Vector3 global(0., 0., 0.);
0503         global = geometry->getGlobalPosition(cluster_key, trkrCluster);
0504         SiClus_trackid.push_back(track->get_id());
0505         SiClus_x.push_back(global[0]);
0506         SiClus_y.push_back(global[1]);
0507         SiClus_z.push_back(global[2]);
0508         int layer = TrkrDefs::getLayer(cluster_key);
0509         h_nlayer->Fill(layer);
0510         if (layer == 3 || layer == 4)
0511           t_inner++;
0512         if (layer == 5 || layer == 6)
0513           t_outer++;
0514         SiClus_layer.push_back(layer);
0515 
0516         int timebkt=-9999;
0517         if(layer<3){
0518           timebkt = MvtxDefs::getStrobeId(cluster_key);
0519         }
0520         else {
0521           timebkt = InttDefs::getTimeBucketId(cluster_key);
0522         }
0523         SiClus_t.push_back(timebkt);
0524       }
0525       track_nmaps.push_back(t_nmaps);
0526       track_nintt.push_back(t_nintt);
0527       track_innerintt.push_back(t_inner);
0528       track_outerintt.push_back(t_outer);
0529     }
0530     track_id.push_back(t_id);
0531     track_x.push_back(t_x);
0532     track_y.push_back(t_y);
0533     track_z.push_back(t_z);
0534     track_eta.push_back(t_eta);
0535     track_phi.push_back(t_phi);
0536     track_pt.push_back(t_pt);
0537     track_px.push_back(t_px);
0538     track_py.push_back(t_py);
0539     track_pz.push_back(t_pz);
0540     track_chi2ndf.push_back(t_chi2ndf);
0541     track_charge.push_back(t_charge);
0542     track_crossing.push_back(t_crossing);
0543     if (false)
0544       std::cout << "track_x : " << t_x << ", track_y: " << t_y << ", track_z: " << t_z 
0545                 << ", track_eta: " << t_eta << ", track_phi: " << t_phi << ", track_pt: " << t_pt << std::endl;
0546 
0547     SvtxTrackState *emcalState    = track->get_state(_caloRadiusEMCal);
0548     SvtxTrackState *emcalOutState = track->get_state(_caloRadiusEMCal+_caloThicknessEMCal);
0549     fillEMCalState(emcalState, emcalOutState);
0550 
0551     if (t_charge > 0)
0552       ntrack_isposcharge.second++;
0553     else
0554       ntrack_isposcharge.first++;
0555 
0556     h_ntrack->Fill(t_eta, t_phi);
0557     h_nmaps->Fill(t_nmaps);
0558     h_nintt->Fill(t_nintt);
0559     h_nmaps_nintt->Fill(t_nmaps, t_nintt);
0560     h_avgnclus_eta_phi->Fill(t_eta, t_phi, t_nmaps + t_nintt);
0561     h_trackcrossing->Fill(t_crossing);
0562     h_trackchi2ndf->Fill(t_chi2ndf);
0563     h_trackpt_inclusive->Fill(t_pt);
0564     if (t_charge > 0)
0565       h_trackpt_pos->Fill(t_pt);
0566     else
0567       h_trackpt_neg->Fill(t_pt);
0568     if (!b_skipvtx)
0569     {
0570       Acts::Vector3 zero = Acts::Vector3::Zero();
0571       auto dcapair_origin = TrackAnalysisUtils::get_dca(track, zero);
0572       auto trackvtx = vertexmap->get(track->get_vertex_id());
0573       if (!trackvtx)
0574       {
0575         ntrack_isfromvtx.first++;
0576         continue;
0577       }
0578       ntrack_isfromvtx.second++;
0579       Acts::Vector3 track_vtx(trackvtx->get_x(), trackvtx->get_y(), trackvtx->get_z());
0580       auto dcapair_vtx = TrackAnalysisUtils::get_dca(track, track_vtx);
0581 
0582       h_dcaxyorigin_phi->Fill(t_phi, dcapair_origin.first.first);
0583       h_dcaxyvtx_phi->Fill(t_phi, dcapair_vtx.first.first);
0584       h_dcazorigin_phi->Fill(t_phi, dcapair_origin.second.first);
0585       h_dcazvtx_phi->Fill(t_phi, dcapair_vtx.second.first);
0586     }
0587   }
0588   //--std::cout << "Track vector sizes: id=" << track_id.size()
0589   //--          << ", x=" << track_x.size()
0590   //--          << ", cluster_x=" << SiClus_x.size()
0591   //--          << ", emc_x=" << track_x_emc.size()
0592   //--          << std::endl;
0593 
0594   // Print all track vector sizes and highlight mismatches
0595   bool size_mismatch = false;
0596   size_t size_ref = track_id.size();
0597   std::vector<std::pair<std::string, size_t>> track_vector_sizes = {
0598     {"track_id", track_id.size()},
0599     {"track_x", track_x.size()},
0600     {"track_y", track_y.size()},
0601     {"track_z", track_z.size()},
0602     {"track_px", track_px.size()},
0603     {"track_py", track_py.size()},
0604     {"track_pz", track_pz.size()},
0605     {"track_eta", track_eta.size()},
0606     {"track_phi", track_phi.size()},
0607     {"track_pt", track_pt.size()},
0608     {"track_chi2ndf", track_chi2ndf.size()},
0609     {"track_charge", track_charge.size()},
0610     {"track_crossing", track_crossing.size()},
0611     {"track_nmaps", track_nmaps.size()},
0612     {"track_nintt", track_nintt.size()},
0613     {"track_innerintt", track_innerintt.size()},
0614     {"track_outerintt", track_outerintt.size()},
0615     {"track_x_emc", track_x_emc.size()},
0616     {"track_y_emc", track_y_emc.size()},
0617     {"track_z_emc", track_z_emc.size()},
0618     {"track_px_emc", track_px_emc.size()},
0619     {"track_py_emc", track_py_emc.size()},
0620     {"track_pz_emc", track_pz_emc.size()},
0621     {"track_eta_emc", track_eta_emc.size()},
0622     {"track_phi_emc", track_phi_emc.size()},
0623     {"track_pt_emc", track_pt_emc.size()}
0624   };
0625   for (const auto& [name, size] : track_vector_sizes)
0626   {
0627     if (size != size_ref)
0628     {
0629       std::cout << "Size mismatch: " << name << " = " << size << " (expected " << size_ref << ")" << std::endl;
0630       size_mismatch = true;
0631     }
0632   }
0633   if (!size_mismatch)
0634   {
0635     //--std::cout << "All track vectors have matching sizes: " << size_ref << std::endl;
0636   }
0637   else
0638   {
0639     std::cout << "WARNING: Detected mismatch in track vector sizes." << std::endl;
0640   }
0641   
0642   trackTree->Fill();
0643 
0644   SiClusTree->Fill();
0645   h_ntrack_isfromvtx->SetBinContent(1, h_ntrack_isfromvtx->GetBinContent(1) + ntrack_isfromvtx.first);
0646   h_ntrack_isfromvtx->SetBinContent(2, h_ntrack_isfromvtx->GetBinContent(2) + ntrack_isfromvtx.second);
0647   h_ntrack_IsPosCharge->SetBinContent(1, h_ntrack_IsPosCharge->GetBinContent(1) + ntrack_isposcharge.first);
0648   h_ntrack_IsPosCharge->SetBinContent(2, h_ntrack_IsPosCharge->GetBinContent(2) + ntrack_isposcharge.second);
0649 
0650   //--std::cout << "EVENT " << evt << " is OK" << std::endl;
0651 
0652   evt++;
0653 }
0654 
0655 void SiliconSeedsAna::processSiCluster(PHCompositeNode* topNode)
0656 {
0657   evt_nintt = evt_nintt50 = evt_nmaps = 0;
0658 
0659   auto geometry   = findNode::getClass<ActsGeometry>(topNode, m_actsgeometryName);
0660   auto clustermap = findNode::getClass<TrkrClusterContainer>(topNode, m_clusterContainerName);
0661   if (!clustermap)
0662   {
0663     std::cout << PHWHERE << "Missing clustermap, can't continue" << std::endl;
0664     return;
0665   }
0666   if (!geometry)
0667   {
0668     std::cout << PHWHERE << "Missing geometry, can't continue" << std::endl;
0669     return;
0670   }
0671 
0672   SiClus_trackid.clear();
0673   SiClus_layer.clear();
0674   SiClus_x.clear();
0675   SiClus_y.clear();
0676   SiClus_z.clear();
0677   SiClus_t.clear();
0678 
0679   int nhits[7]   = {0,0,0,0,0,0,0};
0680   int nhits50[7] = {0,0,0,0,0,0,0};
0681 
0682   for (unsigned int layer = 0; layer < 7; layer++) // layer:0-2 MVTX, 3-7 INTT
0683   {
0684     TrkrDefs::TrkrId detid = (layer<3) ? TrkrDefs::TrkrId::mvtxId : TrkrDefs::TrkrId::inttId;
0685 
0686     for (const auto &hitsetkey : clustermap->getHitSetKeys(detid, layer))
0687     {
0688       auto range = clustermap->getClusters(hitsetkey);
0689 
0690       for (auto clusIter = range.first; clusIter != range.second; ++clusIter)
0691       {
0692         const auto &cluster_key = clusIter->first;
0693         auto cluster            = clusIter->second;
0694 
0695         int timebkt=-9999;
0696         if(layer<3){
0697           timebkt = MvtxDefs::getStrobeId(cluster_key);
0698         }
0699         else {
0700           timebkt = InttDefs::getTimeBucketId(cluster_key);
0701         }
0702 
0703         if(-1<=timebkt&&timebkt<=1){
0704           Acts::Vector3 global(0., 0., 0.);
0705           global = geometry->getGlobalPosition(cluster_key, cluster);
0706 
0707           SiClus_trackid.push_back(-1);
0708           SiClus_x.push_back(global[0]);
0709           SiClus_y.push_back(global[1]);
0710           SiClus_z.push_back(global[2]);
0711           SiClus_layer.push_back(layer);
0712           SiClus_t.push_back(timebkt);
0713 
0714           nhits[layer]++;
0715         }
0716         if(0<=timebkt&&timebkt<50)  nhits50[layer]++;
0717       }
0718     }
0719   }
0720   SiClusAllTree->Fill();
0721 
0722   evt_nmaps = nhits[0]+nhits[1]+nhits[2];
0723   evt_nintt = nhits[3]+nhits[4]+nhits[5]+nhits[6];
0724   evt_nintt50=nhits50[3]+nhits50[4]+nhits50[5]+nhits50[6]; 
0725 
0726 }
0727 
0728 
0729 void SiliconSeedsAna::processCaloClusters(PHCompositeNode* topNode)
0730 {
0731   auto EMCalClusmap = findNode::getClass<RawClusterContainer>(topNode, m_emcalClusName);
0732   clearCaloVectors();
0733   if((calo_evt%1000)==0) std::cout << "start calo map  EVENT " << calo_evt << " is OK" << std::endl;
0734   
0735   evt_nemc = evt_nemc02=0;
0736 
0737   if (!b_skipcalo && EMCalClusmap)
0738   {
0739     //--std::cout<<"start EMCalClusmap " << std::endl;
0740     //--std::cout << "EMCalClusmap size: " << EMCalClusmap->size() << std::endl;
0741     evt_nemc = EMCalClusmap->size();
0742     for (unsigned int i = 0; i < EMCalClusmap->size(); i++)
0743     {
0744       RawCluster *clus = EMCalClusmap->getCluster(i);
0745       if (!clus)
0746         continue;
0747       if (clus->get_energy() < m_emcal_low_cut)
0748         continue;
0749 
0750       calo_x.push_back(clus->get_x());
0751       calo_y.push_back(clus->get_y());
0752       calo_z.push_back(clus->get_z());
0753       calo_r.push_back(clus->get_r());
0754       calo_phi.push_back(clus->get_phi());
0755       float eta = -1.0;
0756       float cx = clus->get_x();
0757       float cy = clus->get_y();
0758       float cz = clus->get_z();
0759       float vx = 0.0, vy = 0.0, vz = 0.0;
0760 
0761       if (!b_skipvtx)
0762       {
0763         auto vertexmap = findNode::getClass<SvtxVertexMap>(topNode, m_vertexMapName);
0764         if (vertexmap && !vertexmap->empty())
0765         {
0766           SvtxVertex *vtx = vertexmap->begin()->second;
0767           if (vtx)
0768           {
0769             vx = vtx->get_x();
0770             vy = vtx->get_y();
0771             vz = vtx->get_z();
0772           }
0773         }
0774       }
0775       float dx = cx - vx;
0776       float dy = cy - vy;
0777       float dz = cz - vz;
0778       float dr = std::sqrt(dx * dx + dy * dy);
0779       float theta = std::atan2(dr, dz);
0780       eta = -std::log(std::tan(theta / 2.0));
0781       calo_eta.push_back(eta);
0782 
0783       float energy =clus->get_energy();
0784       calo_energy.push_back(energy);
0785       calo_chi2.push_back(clus->get_chi2());
0786       calo_prob.push_back(clus->get_prob());
0787 
0788       if(energy>0.2) evt_nemc02++;
0789 
0790       //--std::cout << "EMCal x : " << calo_x.back() << ", EMCal y :  " << calo_y.back() << ", EMCal z : " << calo_z.back() 
0791       //--          << ", EMCal r : " << calo_r.back() << ", EMCal phi :  " << calo_phi.back() 
0792       //--          << ", EMCal eta : " << calo_eta.back() << ", EMcal E : " << calo_energy.back() << std::endl;
0793     }
0794     caloTree->Fill();
0795   }
0796   else
0797   {
0798     std::cout << "No EMCal clusters found, skipping EMCal processing." << std::endl;
0799   }
0800   //--std::cout << "Number of calo clusters: " << calo_energy.size()
0801   //--          << ", calo event : " << calo_evt << std::endl;
0802   calo_evt++;
0803 }
0804 
0805 void SiliconSeedsAna::processVertexMap(PHCompositeNode* topNode)
0806 {
0807   auto vertexmap = findNode::getClass<SvtxVertexMap>(topNode, m_vertexMapName);
0808   if (!vertexmap)
0809   {
0810     std::cout << PHWHERE << "Missing vertexmap, can't continue" << std::endl;
0811     return;
0812   }
0813   h_nvertex->Fill(vertexmap->size());
0814 
0815   if((evt%1000)==0) std::cout << "start VTX map  EVENT " << evt << " is OK" << std::endl;
0816 
0817   for (const auto &[key, vertex] : *vertexmap)
0818   {
0819     if (!vertex)
0820     {
0821       continue;
0822     }
0823     float vx = vertex->get_x();
0824     float vy = vertex->get_y();
0825     float vz = vertex->get_z();
0826     float vt = vertex->get_t0();
0827     float vchi2 = vertex->get_chisq();
0828     int vndof = vertex->get_ndof();
0829     int vcrossing = vertex->get_beam_crossing();
0830     if (vcrossing != 0)
0831       continue;
0832     h_vx->Fill(vx);
0833     h_vy->Fill(vy);
0834     h_vx_vy->Fill(vx, vy);
0835     h_vz->Fill(vz);
0836     h_vt->Fill(vt);
0837     h_vchi2dof->Fill(float(vchi2 / vndof));
0838     h_vcrossing->Fill(vcrossing);
0839     h_ntrackpervertex->Fill(vertex->size_tracks());
0840 
0841     evt_xvtx = vx;
0842     evt_yvtx = vy;
0843     evt_zvtx = vz;
0844   }
0845 }
0846 
0847 //____________________________________________________________________________..
0848 int SiliconSeedsAna::EndRun(const int /*runnumber*/)
0849 {
0850   if(m_outfile==nullptr) {
0851     std::cout<<"OutputFile is not open. No histogram saved"<<std::endl;
0852     return Fun4AllReturnCodes::EVENT_OK;
0853   }
0854   m_outfile->cd();
0855 
0856   std::cout << "Writing histograms to " << m_outputfilename << std::endl;
0857   // Create a TFile to save histograms and TTree
0858   //  TFile outfile("output_histograms.root", "RECREATE");
0859   //TFile outfile(m_outputfilename.c_str(), "RECREATE");
0860 
0861   // Write histograms to the file
0862   h_nlayer->Write();
0863   h_nmaps->Write();
0864   h_nintt->Write();
0865   h_nmaps_nintt->Write();
0866   h_ntrack1d->Write();
0867   h_ntrack->Write();
0868   h_avgnclus_eta_phi->Write();
0869   h_trackcrossing->Write();
0870   h_trackchi2ndf->Write();
0871   h_dcaxyorigin_phi->Write();
0872   h_dcaxyvtx_phi->Write();
0873   h_dcazorigin_phi->Write();
0874   h_dcazvtx_phi->Write();
0875   h_ntrack_isfromvtx->Write();
0876   h_trackpt_inclusive->Write();
0877   h_trackpt_pos->Write();
0878   h_trackpt_neg->Write();
0879   h_ntrack_IsPosCharge->Write();
0880   h_nvertex->Write();
0881   h_vx->Write();
0882   h_vy->Write();
0883   h_vx_vy->Write();
0884   h_vz->Write();
0885   h_vt->Write();
0886   h_vcrossing->Write();
0887   h_vchi2dof->Write();
0888   h_ntrackpervertex->Write();
0889 
0890   // Write the TTree to the file
0891   if (trackTree)
0892   {
0893     trackTree->Write();
0894   }
0895   if(SiClusTree)
0896   {
0897     SiClusTree->Write();
0898   }
0899   if(SiClusAllTree)
0900   {
0901     SiClusAllTree->Write();
0902   }
0903   if (caloTree)
0904   {
0905     caloTree->Write();
0906   }
0907   if (evtTree)
0908   {
0909     evtTree->Write();
0910   }
0911   if (truthTree && truthTree->GetEntries() > 0)
0912   {
0913     truthTree->Write();
0914   }
0915   // Close the file
0916   m_outfile->Close();
0917 
0918   return Fun4AllReturnCodes::EVENT_OK;
0919 }
0920 
0921 //____________________________________________________________________________..
0922 int SiliconSeedsAna::End(PHCompositeNode * /*unused*/)
0923 {
0924   return Fun4AllReturnCodes::EVENT_OK;
0925 }
0926 
0927 std::string SiliconSeedsAna::getHistoPrefix() const
0928 {
0929   return std::string("h_") + Name() + std::string("_");
0930 }
0931 
0932 void SiliconSeedsAna::createHistos()
0933 {
0934   {
0935     h_nlayer = new TH1F(std::string(getHistoPrefix() + "nlayer").c_str(), "layer clusters per track;Number of layer clusters per track;Entries", 14, -0.5, 13.5);
0936   }
0937 
0938   {
0939     h_nmaps = new TH1F(std::string(getHistoPrefix() + "nmaps").c_str(), "MVTX clusters per track;Number of MVTX clusters per track;Entries", 7, -0.5, 6.5);
0940   }
0941 
0942   {
0943     h_nintt = new TH1F(std::string(getHistoPrefix() + "nintt").c_str(), "INTT clusters per track;Number of INTT clusters per track;Entries", 7, -0.5, 6.5);
0944   }
0945 
0946   {
0947     h_nmaps_nintt = new TH2F(std::string(getHistoPrefix() + "nmaps_nintt").c_str(), "MVTX vs INTT clusters per track;Number of MVTX clusters per track;Number of INTT clusters per track;Entries", 7, -0.5, 6.5, 7, -0.5, 6.5);
0948   }
0949 
0950   {
0951     h_ntrack1d = new TH1F(std::string(getHistoPrefix() + "nrecotracks1d").c_str(), "Number of reconstructed tracks;Number of silicon tracklets;Entries", 200, 0, 200);
0952   }
0953 
0954   {
0955     h_ntrack = new TH2F(std::string(getHistoPrefix() + "nrecotracks").c_str(), "Number of reconstructed tracks;#eta;#phi [rad];Entries", 100, -1.1, 1.1, 300, -3.14159, 3.1459);
0956   }
0957 
0958   {
0959     h_avgnclus_eta_phi = new TProfile2D(std::string(getHistoPrefix() + "avgnclus_eta_phi").c_str(), "Average number of clusters per track;#eta;#phi [rad];Average number of clusters per track", 100, -1.1, 1.1, 300, -3.14159, 3.1459, 0, 10);
0960   }
0961 
0962   {
0963     h_trackcrossing = new TH1F(std::string(getHistoPrefix() + "trackcrossing").c_str(), "Track beam bunch crossing;Track crossing;Entries", 110, -10, 100);
0964   }
0965 
0966   {
0967     h_trackchi2ndf = new TH1F(std::string(getHistoPrefix() + "trackchi2ndf").c_str(), "Track chi2/ndof;Track #chi2/ndof;Entries", 100, 0, 20);
0968   }
0969 
0970   {
0971     h_dcaxyorigin_phi = new TH2F(std::string(getHistoPrefix() + "dcaxyorigin_phi").c_str(), "DCA xy origin vs phi;#phi [rad];DCA_{xy} wrt origin [cm];Entries", 300, -3.14159, 3.1459, 90, -3, 3);
0972   }
0973 
0974   {
0975     h_dcaxyvtx_phi = new TH2F(std::string(getHistoPrefix() + "dcaxyvtx_phi").c_str(), "DCA xy vertex vs phi;#phi [rad];DCA_{xy} wrt vertex [cm];Entries", 300, -3.14159, 3.1459, 90, -3, 3);
0976   }
0977 
0978   {
0979     h_dcazorigin_phi = new TH2F(std::string(getHistoPrefix() + "dcazorigin_phi").c_str(), "DCA z origin vs phi;#phi [rad];DCA_{z} wrt origin [cm];Entries", 300, -3.14159, 3.1459, 160, -20, 20);
0980   }
0981 
0982   {
0983     h_dcazvtx_phi = new TH2F(std::string(getHistoPrefix() + "dcazvtx_phi").c_str(), "DCA z vertex vs phi;#phi [rad];DCA_{z} wrt vertex [cm];Entries", 300, -3.14159, 3.1459, 160, -20, 20);
0984   }
0985 
0986   {
0987     h_ntrack_isfromvtx = new TH1F(std::string(getHistoPrefix() + "ntrack_isfromvtx").c_str(), "Num of tracks associated to a vertex;Is track associated to a vertex;Entries", 2, -0.5, 1.5);
0988   }
0989 
0990   {
0991     h_trackpt_inclusive = new TH1F(std::string(getHistoPrefix() + "trackpt").c_str(), "Track p_{T};p_{T} [GeV/c];Entries", 100, 0, 10);
0992   }
0993 
0994   {
0995     h_trackpt_pos = new TH1F(std::string(getHistoPrefix() + "trackpt_pos").c_str(), "Track p_{T} positive;Positive track p_{T} [GeV/c];Entries", 100, 0, 10);
0996   }
0997 
0998   {
0999     h_trackpt_neg = new TH1F(std::string(getHistoPrefix() + "trackpt_neg").c_str(), "Track p_{T} negative;Negative track p_{T} [GeV/c];Entries", 100, 0, 10);
1000   }
1001 
1002   {
1003     h_ntrack_IsPosCharge = new TH1F(std::string(getHistoPrefix() + "ntrack_IsPosCharge").c_str(), "Num of tracks with positive charge;Is track positive charged;Entries", 2, -0.5, 1.5);
1004   }
1005 
1006   // vertex
1007   {
1008     h_nvertex = new TH1F(std::string(getHistoPrefix() + "nrecovertices").c_str(), "Num of reco vertices per event;Number of vertices;Entries", 20, 0, 20);
1009   }
1010 
1011   {
1012     h_vx = new TH1F(std::string(getHistoPrefix() + "vx").c_str(), "Vertex x;Vertex x [cm];Entries", 100, -2.5, 2.5);
1013   }
1014 
1015   {
1016     h_vy = new TH1F(std::string(getHistoPrefix() + "vy").c_str(), "Vertex y;Vertex y [cm];Entries", 100, -2.5, 2.5);
1017   }
1018 
1019   {
1020     h_vx_vy = new TH2F(std::string(getHistoPrefix() + "vx_vy").c_str(), "Vertex x vs y;Vertex x [cm];Vertex y [cm];Entries", 100, -2.5, 2.5, 100, -2.5, 2.5);
1021   }
1022 
1023   {
1024     h_vz = new TH1F(std::string(getHistoPrefix() + "vz").c_str(), "Vertex z;Vertex z [cm];Entries", 50, -25, 25);
1025   }
1026 
1027   {
1028     h_vt = new TH1F(std::string(getHistoPrefix() + "vt").c_str(), "Vertex t;Vertex t [ns];Entries", 100, -1000, 20000);
1029   }
1030 
1031   {
1032     h_vcrossing = new TH1F(std::string(getHistoPrefix() + "vertexcrossing").c_str(), "Vertex beam bunch crossing;Vertex crossing;Entries", 100, -100, 300);
1033   }
1034 
1035   {
1036     h_vchi2dof = new TH1F(std::string(getHistoPrefix() + "vertexchi2dof").c_str(), "Vertex chi2/ndof;Vertex #chi2/ndof;Entries", 100, 0, 20);
1037   }
1038 
1039   {
1040     h_ntrackpervertex = new TH1F(std::string(getHistoPrefix() + "ntrackspervertex").c_str(), "Num of tracks per vertex;Number of tracks per vertex;Entries", 50, 0, 50);
1041   }
1042 }
1043 
1044 void SiliconSeedsAna::createTree()
1045 {
1046 }