Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-12-19 09:18:40

0001 #include "pi0EtaByEta.h"
0002 
0003 #include <g4main/PHG4TruthInfoContainer.h>
0004 #include <g4main/PHG4VtxPoint.h>
0005 
0006 #include <globalvertex/GlobalVertex.h>
0007 #include <globalvertex/GlobalVertexMap.h>
0008 #include <globalvertex/Vertex.h>
0009 
0010 // Tower includes
0011 #include <calobase/RawCluster.h>
0012 #include <calobase/RawClusterContainer.h>
0013 #include <calobase/RawClusterUtility.h>
0014 #include <calobase/RawTowerGeomContainer.h>
0015 #include <calobase/TowerInfo.h>
0016 #include <calobase/TowerInfoContainer.h>
0017 #include <calobase/TowerInfoDefs.h>
0018 
0019 #include <calotrigger/TriggerAnalyzer.h>
0020 #include <ffarawobjects/Gl1Packet.h>
0021 
0022 #include <cdbobjects/CDBTTree.h>  // for CDBTTree
0023 
0024 #include <fun4all/Fun4AllHistoManager.h>
0025 #include <fun4all/Fun4AllReturnCodes.h>
0026 #include <fun4all/SubsysReco.h>  // for SubsysReco
0027 
0028 #include <phool/getClass.h>
0029 #include <phool/phool.h>
0030 
0031 #include <TF1.h>
0032 #include <TFile.h>
0033 #include <TH1.h>
0034 #include <TH2.h>
0035 #include <TH3.h>
0036 #include <TLorentzVector.h>
0037 #include <TNtuple.h>
0038 #include <TStyle.h>
0039 #include <TSystem.h>
0040 #include <TTree.h>
0041 
0042 #include <CLHEP/Vector/ThreeVector.h>  // for Hep3Vector
0043 
0044 #include <cmath>    // for fabs, isnan, M_PI
0045 #include <cstdint>  // for exit
0046 #include <cstdlib>  // for exit
0047 #include <filesystem>
0048 #include <iostream>
0049 #include <map>        // for operator!=, _Rb_tree_con...
0050 #include <stdexcept>  // for runtime_error
0051 #include <string>
0052 #include <utility>
0053 
0054 pi0EtaByEta::pi0EtaByEta(const std::string& name, const std::string& filename)
0055   : SubsysReco(name)
0056   , detector("HCALIN")
0057   , outfilename(filename)
0058 {
0059   h_mass_eta_lt.fill(nullptr);
0060 
0061   if (runTowByTow)
0062   {
0063     for (auto& row : h_mass_tbt_lt)
0064     {
0065       row.fill(nullptr);
0066     }
0067   }
0068 
0069   clusMix = new std::vector<std::vector<std::vector<CLHEP::Hep3Vector>>>();
0070 }
0071 
0072 pi0EtaByEta::~pi0EtaByEta()
0073 {
0074   delete hm;
0075   delete g4hitntuple;
0076   delete g4cellntuple;
0077   delete towerntuple;
0078   delete clusterntuple;
0079 }
0080 
0081 int pi0EtaByEta::Init(PHCompositeNode* /*unused*/)
0082 {
0083   hm = new Fun4AllHistoManager(Name());
0084   // create and register your histos (all types) here
0085 
0086   outfile = new TFile(outfilename.c_str(), "RECREATE");
0087 
0088   // correlation plots
0089   for (int i = 0; i < 96; i++)
0090   {
0091     std::string histoname = "h_mass_eta_lt" + std::to_string(i);
0092     h_mass_eta_lt[i] = new TH1F(histoname.c_str(), "", 50, 0, 0.5);
0093 
0094     if (runTowByTow)
0095     {
0096       for (int j = 0; j < 256; j++)
0097       {
0098         std::string histoname_tbt = "h_mass_tbt_lt_" + std::to_string(i) + "_" + std::to_string(j);
0099         h_mass_tbt_lt[i][j] = new TH1F(histoname_tbt.c_str(), "", 50, 0, 0.5);
0100       }
0101     }
0102   }
0103 
0104   // 3D hist to save inv mass for all towers
0105   if (runTBTCompactMode)
0106   {
0107     h_ieta_iphi_invmass = new TH3F("h_ieta_iphi_invmass", "", 96, 0, 96, 256, 0, 256, 50, 0.0, 0.5);
0108   }
0109 
0110   h_cemc_etaphi = new TH2F("h_cemc_etaphi", "", 96, 0, 96, 256, 0, 256);
0111   h_cemc_etaphi_noCalib = new TH2F("h_cemc_etaphi_noCalib", "", 96, 0, 96, 256, 0, 256);
0112 
0113   // 1D distributions
0114   h_InvMass = new TH1F("h_InvMass", "Invariant Mass", 240, 0, 1.2);
0115   h_InvMassMix = new TH1F("h_InvMassMix", "Invariant Mass", 120, 0, 1.2);
0116 
0117   // cluster QA
0118   h_etaphi_clus = new TH2F("h_etaphi_clus", "", 140, -1.2, 1.2, 64, -1 * M_PI, M_PI);
0119   h_clus_pt = new TH1F("h_clus_pt", "", 100, 0, 10);
0120 
0121   h_emcal_e_eta = new TH1F("h_emcal_e_eta", "", 96, 0, 96);
0122 
0123   h_pt1 = new TH1F("h_pt1", "", 100, 0, 5);
0124   h_pt2 = new TH1F("h_pt2", "", 100, 0, 5);
0125 
0126   h_nclusters = new TH1F("h_nclusters", "", 1000, 0, 1000);
0127   h_m_pt = new TH2F("h_m_pt","",350,0,0.7,30,0,15);
0128   h_m_IB = new TH2F("h_m_IB","",300,0,1.0,384, -0.5, 383.5);
0129 
0130   h_event = new TH1F("h_event", "", 1, 0, 1);
0131 
0132   h_tower_e = new TH1F("h_tower_e","",1000,-1,5);
0133 
0134   std::vector<std::vector<CLHEP::Hep3Vector>> temp2 = std::vector<std::vector<CLHEP::Hep3Vector>>();
0135   std::vector<CLHEP::Hep3Vector> temp = std::vector<CLHEP::Hep3Vector>();
0136   for (int i = 0; i < NBinsVtx; i++)
0137   {
0138     temp2.push_back(temp);
0139   }
0140   for (int i = 0; i < NBinsClus; i++)
0141   {
0142     clusMix->push_back(temp2);
0143   }
0144 
0145   trigAna = new TriggerAnalyzer();
0146 
0147   return 0;
0148 }
0149 
0150 int pi0EtaByEta::process_event(PHCompositeNode* topNode)
0151 {
0152   _eventcounter++;
0153 
0154   process_towers(topNode);
0155 
0156   return Fun4AllReturnCodes::EVENT_OK;
0157 }
0158 
0159 int pi0EtaByEta::process_towers(PHCompositeNode* topNode)
0160 {
0161   if ((_eventcounter % 1000) == 0)
0162   {
0163     std::cout << _eventcounter << std::endl;
0164   }
0165 
0166   // float emcaldownscale = 1000000 / 800;
0167 
0168   float emcal_hit_threshold = 0.3;  // GeV
0169 
0170   // cuts
0171   float maxDr = 1.1;
0172   float maxAlpha = 0.6;
0173   float clus_chisq_cut = 0.05;
0174   float nClus_ptCut = 0.5;
0175   int max_nClusCount = 300;
0176 
0177   //--------------------------- trigger and GL1-------------------------------//
0178 
0179   if (reqTrig)
0180   {
0181     trigAna->decodeTriggers(topNode);
0182     bool fireTrig = false;
0183     for (auto bit : triggerList)
0184     {
0185       if (trigAna->didTriggerFire(bit) == true)
0186       {
0187         fireTrig = true;
0188       }
0189     }
0190     if (!fireTrig)
0191     {
0192       return Fun4AllReturnCodes::EVENT_OK;
0193     }
0194   }
0195 
0196   //----------------------------------get vertex------------------------------------------------------//
0197   GlobalVertexMap* vertexmap = findNode::getClass<GlobalVertexMap>(topNode, "GlobalVertexMap");
0198   if (!vertexmap)
0199   {
0200     // std::cout << PHWHERE << " Fatal Error - GlobalVertexMap node is missing"<< std::endl;
0201     std::cout << "pi0EtaByEta GlobalVertexMap node is missing" << std::endl;
0202     // return Fun4AllReturnCodes::ABORTRUN;
0203   }
0204 
0205   float vtx_z = 0;
0206   bool found_vertex = false;
0207   if (vertexmap && !vertexmap->empty())
0208   {
0209     GlobalVertex* vtx = vertexmap->begin()->second;
0210     if (vtx)
0211     {
0212       if (m_use_vertextype)
0213       {
0214         auto typeStartIter = vtx->find_vertexes(m_vertex_type);
0215         auto typeEndIter = vtx->end_vertexes();
0216         for (auto iter = typeStartIter; iter != typeEndIter; ++iter)
0217         {
0218           const auto& [type, vertexVec] = *iter;
0219           if (type != m_vertex_type)
0220           {
0221             continue;
0222           }
0223           for (const auto* vertex : vertexVec)
0224           {
0225             if (!vertex)
0226             {
0227               continue;
0228             }
0229             vtx_z = vertex->get_z();
0230             found_vertex = true;
0231           }
0232         }
0233       }
0234       else
0235       {
0236         vtx_z = vtx->get_z();
0237         found_vertex = true;
0238       }
0239     }
0240   }
0241 
0242   //////////////////////////////                                                                  // truth vertex
0243   PHG4TruthInfoContainer* truthinfo = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
0244   float vtx_z_tr = -999;
0245   if (truthinfo)
0246   {
0247     PHG4TruthInfoContainer::VtxRange vtxrange = truthinfo->GetVtxRange();
0248     for (PHG4TruthInfoContainer::ConstVtxIterator iter = vtxrange.first; iter != vtxrange.second; ++iter)
0249     {
0250       PHG4VtxPoint* vtx_tr = iter->second;
0251       if (vtx_tr->get_id() == 1)
0252       {
0253         vtx_z_tr = vtx_tr->get_z();
0254       }
0255     }
0256     if (vtx_z_tr != -999)
0257     {
0258       vtx_z = vtx_z_tr;
0259     }
0260   }
0261 
0262   if (useVertexTruth == true)
0263   {
0264     found_vertex = true;
0265     vtx_z = vtx_z_tr;
0266   }
0267 
0268   if (!found_vertex && reqVertex)
0269   {
0270     return Fun4AllReturnCodes::EVENT_OK;
0271   }
0272 
0273 
0274   TowerInfoContainer* towers = findNode::getClass<TowerInfoContainer>(topNode, "TOWERINFO_CALIB_CEMC");
0275   if (towers)
0276   {
0277     int size = towers->size();
0278     for (int channel = 0; channel < size; channel++)
0279     {
0280       TowerInfo* tower = towers->get_tower_at_channel(channel);
0281       float offlineenergy = tower->get_energy();
0282       unsigned int towerkey = towers->encode_key(channel);
0283       int ieta = towers->getTowerEtaBin(towerkey);
0284       int iphi = towers->getTowerPhiBin(towerkey);
0285       bool isGood = tower->get_isGood();
0286       if (isGood)
0287       {
0288         h_tower_e->Fill(offlineenergy);
0289       }
0290       if (offlineenergy > emcal_hit_threshold && isGood)
0291       {
0292         h_cemc_etaphi->Fill(ieta, iphi);
0293       }
0294       if (tower->get_isNoCalib())
0295       {
0296         h_cemc_etaphi_noCalib->Fill(ieta, iphi);
0297       }
0298     }
0299   }
0300 
0301   std::string cluster_node_name = "CLUSTERINFO_CEMC";
0302 
0303   if (use_pdc)
0304   {
0305     cluster_node_name = "CLUSTERINFO_POS_COR_CEMC";
0306   }
0307   RawClusterContainer* clusterContainer = findNode::getClass<RawClusterContainer>(topNode, cluster_node_name);
0308   if (!clusterContainer)
0309   {
0310     std::cout << PHWHERE << "funkyCaloStuff::process_event - Fatal Error - CLUSTER_CEMC node is missing. " << std::endl;
0311     return 0;
0312   }
0313 
0314   //////////////////////////////////////////
0315   // geometry for hot tower/cluster masking
0316   std::string towergeomnodename = "TOWERGEOM_CEMC";
0317   RawTowerGeomContainer* m_geometry = findNode::getClass<RawTowerGeomContainer>(topNode, towergeomnodename);
0318   if (!m_geometry)
0319   {
0320     std::cout << Name() << "::"
0321               << "CreateNodeTree"
0322               << ": Could not find node " << towergeomnodename << std::endl;
0323     throw std::runtime_error("failed to find TOWERGEOM node in RawClusterDeadHotMask::CreateNodeTree");
0324   }
0325 
0326   /////////////////////////////
0327   // clusters
0328   RawClusterContainer::ConstRange clusterEnd = clusterContainer->getClusters();
0329   RawClusterContainer::ConstIterator clusterIter;
0330   RawClusterContainer::ConstIterator clusterIter2;
0331   int nClusCount = 0;
0332   for (clusterIter = clusterEnd.first; clusterIter != clusterEnd.second; clusterIter++)
0333   {
0334     RawCluster* recoCluster = clusterIter->second;
0335 
0336     CLHEP::Hep3Vector vertex(0, 0, vtx_z);
0337     CLHEP::Hep3Vector E_vec_cluster = RawClusterUtility::GetECoreVec(*recoCluster, vertex);
0338 
0339     float clus_pt = E_vec_cluster.perp();
0340     float clus_chisq = recoCluster->get_prob();
0341 
0342     if (clus_pt < nClus_ptCut)
0343     {
0344       continue;
0345     }
0346     if (clus_chisq < clus_chisq_cut)
0347     {
0348       continue;
0349     }
0350     nClusCount++;
0351   }
0352 
0353   h_nclusters->Fill(nClusCount);
0354 
0355   if (nClusCount > max_nClusCount)
0356   {
0357     return Fun4AllReturnCodes::EVENT_OK;
0358   }
0359 
0360   if (std::fabs(vtx_z) > vtx_z_cut && doVtxCut)
0361   {
0362     return Fun4AllReturnCodes::EVENT_OK;
0363   }
0364 
0365   h_event->Fill(0);
0366 
0367   float pt1ClusCut = pt1BaseClusCut;
0368   float pt2ClusCut = pt2BaseClusCut;
0369 
0370   if (nClusCount > 30)
0371   {
0372     pt1ClusCut += NclusDeptFac * (nClusCount - 29) / 200.0;
0373     pt2ClusCut += NclusDeptFac * (nClusCount - 29) / 200.0;
0374   }
0375 
0376   float pi0ptcut = 1.22 * (pt1ClusCut + pt2ClusCut);
0377 
0378   for (clusterIter = clusterEnd.first; clusterIter != clusterEnd.second; clusterIter++)
0379   {
0380     RawCluster* recoCluster = clusterIter->second;
0381 
0382     CLHEP::Hep3Vector vertex(0, 0, vtx_z);
0383     CLHEP::Hep3Vector E_vec_cluster = RawClusterUtility::GetECoreVec(*recoCluster, vertex);
0384 
0385     float clusE = E_vec_cluster.mag();
0386     float clus_eta = E_vec_cluster.pseudoRapidity();
0387     float clus_phi = E_vec_cluster.phi();
0388     float clus_pt = E_vec_cluster.perp();
0389     float clus_chisq = recoCluster->get_prob();
0390 
0391     if (clus_chisq < clus_chisq_cut)
0392     {
0393       continue;
0394     }
0395     h_clus_pt->Fill(clus_pt);
0396 
0397     unsigned int lt_eta = recoCluster->get_lead_tower().first;
0398     unsigned int lt_phi = recoCluster->get_lead_tower().second;
0399 
0400     h_etaphi_clus->Fill(clus_eta, clus_phi);
0401 
0402     TLorentzVector photon1;
0403     photon1.SetPtEtaPhiE(clus_pt, clus_eta, clus_phi, clusE);
0404 
0405     if (clus_pt < pt1ClusCut || clus_pt > ptClusMax)
0406     {
0407       continue;
0408     }
0409 
0410     for (clusterIter2 = clusterEnd.first; clusterIter2 != clusterIter; clusterIter2++)
0411     {
0412       RawCluster* recoCluster2 = clusterIter2->second;
0413 
0414       CLHEP::Hep3Vector E_vec_cluster2 = RawClusterUtility::GetECoreVec(*recoCluster2, vertex);
0415 
0416       float clus2E = E_vec_cluster2.mag();
0417       float clus2_eta = E_vec_cluster2.pseudoRapidity();
0418       float clus2_phi = E_vec_cluster2.phi();
0419       float clus2_pt = E_vec_cluster2.perp();
0420       float clus2_chisq = recoCluster2->get_prob();
0421 
0422       // Apply pt cuts to second cluster in the pair
0423       if (clus2_pt < pt2ClusCut || clus2_pt > ptClusMax)
0424       {
0425         continue;
0426       }
0427       if (clus2_chisq < clus_chisq_cut)
0428       {
0429         continue;
0430       }
0431 
0432       TLorentzVector photon2;
0433       photon2.SetPtEtaPhiE(clus2_pt, clus2_eta, clus2_phi, clus2E);
0434 
0435       if (std::fabs(clusE - clus2E) / (clusE + clus2E) > maxAlpha)
0436       {
0437         continue;
0438       }
0439 
0440       if (photon1.DeltaR(photon2) > maxDr)
0441       {
0442         continue;
0443       }
0444 
0445       TLorentzVector pi0 = photon1 + photon2;
0446       if (pi0.Pt() < pi0ptcut)
0447       {
0448         continue;
0449       }
0450 
0451       h_pt1->Fill(photon1.Pt());
0452       h_pt2->Fill(photon2.Pt());
0453       h_m_pt->Fill(pi0.M(),pi0.Pt());
0454 
0455       h_InvMass->Fill(pi0.M());
0456       if (clus2_pt < pt1ClusCut)
0457       {
0458         h_InvMass->Fill(pi0.M());
0459       }
0460 
0461       if (lt_eta > 95)
0462       {
0463         continue;
0464       }
0465       h_mass_eta_lt[lt_eta]->Fill(pi0.M());
0466 
0467       int IB_num = ((lt_eta / 8) * 32) + (lt_phi / 8);
0468       h_m_IB->Fill(pi0.M(),static_cast<double>(IB_num));
0469 
0470       if (runTBTCompactMode)
0471       {
0472         h_ieta_iphi_invmass->Fill(lt_eta, lt_phi, pi0.M());
0473       }  // fill 3D hist for inv mass
0474 
0475       if (runTowByTow)
0476       {
0477         h_mass_tbt_lt[lt_eta][lt_phi]->Fill(pi0.M());
0478       }  // fill 1D inv mass hist for all towers
0479     }
0480   }  // clus1 loop
0481 
0482   return Fun4AllReturnCodes::EVENT_OK;
0483 }
0484 
0485 int pi0EtaByEta::End(PHCompositeNode* /*topNode*/)
0486 {
0487   outfile->cd();
0488 
0489   outfile->Write();
0490   outfile->Close();
0491   delete outfile;
0492   hm->dumpHistos(outfilename, "UPDATE");
0493 
0494   return 0;
0495 }
0496 
0497 TF1* pi0EtaByEta::fitHistogram(TH1* h)
0498 {
0499   TF1* f_sig_initial = new TF1("f_sig_initial", "[0]/[2]/2.5*exp(-0.5*((x-[1])/[2])^2)", 0.05, 0.25);
0500 
0501   f_sig_initial->SetParLimits(0, 0, 10);
0502   f_sig_initial->SetParLimits(1, 0.11, 0.18);
0503   f_sig_initial->SetParLimits(2, 0.007, 0.04);
0504   f_sig_initial->SetParameter(0, 0.1);
0505   f_sig_initial->SetParameter(1, 0.15);
0506   f_sig_initial->SetParameter(2, 0.015);
0507 
0508   h->Fit(f_sig_initial, "QN");
0509 
0510   TF1* fitFunc = new TF1("fitFunc", "[0]/[2]/2.5*exp(-0.5*((x-[1])/[2])^2) + [3] + [4]*x + [5]*x^2 + [6]*x^3", h->GetXaxis()->GetXmin(), h->GetXaxis()->GetXmax());
0511 
0512   fitFunc->SetParameter(0, f_sig_initial->GetParameter(0));
0513   fitFunc->SetParameter(1, f_sig_initial->GetParameter(1));
0514   fitFunc->SetParameter(2, f_sig_initial->GetParameter(2));
0515   fitFunc->SetParameter(3, 0.0);
0516   fitFunc->SetParameter(4, 0.0);
0517   fitFunc->SetParameter(5, 0.0);
0518   fitFunc->SetParameter(6, 0);
0519 
0520   fitFunc->SetParLimits(0, 0, 10);
0521   fitFunc->SetParLimits(1, 0.11, 0.2);
0522   fitFunc->SetParLimits(2, 0.007, 0.05);
0523   fitFunc->SetParLimits(3, -2, 1);
0524   fitFunc->SetParLimits(4, -1, 40);
0525   fitFunc->SetParLimits(5, -150, 50);
0526   // fitFunc->SetParLimits(6, -1,200 );
0527   fitFunc->SetParLimits(6, -1, 1);
0528 
0529   fitFunc->SetRange(0.06, 0.7);
0530 
0531   // Perform the fit
0532   h->Fit("fitFunc", "QN");
0533 
0534   return fitFunc;
0535 }
0536 
0537 void pi0EtaByEta::fitEtaSlices(const std::string& infile, const std::string& fitOutFile, const std::string& cdbFile)
0538 {
0539   TFile* fin = new TFile(infile.c_str());
0540   std::cout << "getting hists" << std::endl;
0541   TH1* h_peak_eta = new TH1F("h_peak_eta", "", 96, 0, 96);
0542   TH1* h_sigma_eta = new TH1F("h_sigma_eta", "", 96, 0, 96);
0543   TH1* h_p3_eta = new TH1F("h_p3_eta", "", 96, 0, 96);
0544   TH1* h_p4_eta = new TH1F("h_p4_eta", "", 96, 0, 96);
0545   TH1* h_p5_eta = new TH1F("h_p5_eta", "", 96, 0, 96);
0546   TH1* h_p6_eta = new TH1F("h_p6_eta", "", 96, 0, 96);
0547   TH1* h_p0_eta = new TH1F("h_p0_eta", "", 96, 0, 96);
0548   if (!fin)
0549   {
0550     std::cout << "pi0EtaByEta::fitEtaSlices null fin" << std::endl;
0551     exit(1);
0552   }
0553   TH1* h_M_eta[96];
0554   for (int i = 0; i < 96; i++)
0555   {
0556     std::string histoname = "h_mass_eta_lt" + std::to_string(i);
0557     fin->GetObject(histoname.c_str(), h_M_eta[i]);
0558     h_M_eta[i]->Scale(1. / h_M_eta[i]->Integral(), "width");
0559   }
0560 
0561   TF1* fitFunOut[96];
0562   for (int i = 0; i < 96; i++)
0563   {
0564     if (!h_M_eta[i])
0565     {
0566       std::cout << "pi0EtaByEta::fitEtaSlices null hist" << std::endl;
0567     }
0568     if (h_M_eta[i]->GetEntries() == 0)
0569     {
0570       continue;
0571     }
0572 
0573     fitFunOut[i] = fitHistogram(h_M_eta[i]);
0574     std::string funcname = "f_pi0_eta" + std::to_string(i);
0575     fitFunOut[i]->SetName(funcname.c_str());
0576     float mass_val_out = fitFunOut[i]->GetParameter(1);
0577     float mass_err_out = fitFunOut[i]->GetParError(1);
0578     h_peak_eta->SetBinContent(i + 1, mass_val_out);
0579     if (std::isnan(h_M_eta[i]->GetEntries()))
0580     {
0581       h_peak_eta->SetBinError(i + 1, 0);
0582       continue;
0583     }
0584     h_peak_eta->SetBinError(i + 1, mass_err_out);
0585     h_sigma_eta->SetBinContent(i + 1, fitFunOut[i]->GetParameter(2));
0586     h_sigma_eta->SetBinError(i + 1, fitFunOut[i]->GetParError(2));
0587     h_p3_eta->SetBinContent(i + 1, fitFunOut[i]->GetParameter(3));
0588     h_p3_eta->SetBinError(i + 1, fitFunOut[i]->GetParError(3));
0589     h_p4_eta->SetBinContent(i + 1, fitFunOut[i]->GetParameter(4));
0590     h_p4_eta->SetBinError(i + 1, fitFunOut[i]->GetParError(4));
0591     h_p5_eta->SetBinContent(i + 1, fitFunOut[i]->GetParameter(5));
0592     h_p5_eta->SetBinError(i + 1, fitFunOut[i]->GetParError(5));
0593     h_p6_eta->SetBinContent(i + 1, fitFunOut[i]->GetParameter(6));
0594     h_p6_eta->SetBinError(i + 1, fitFunOut[i]->GetParError(6));
0595     h_p0_eta->SetBinContent(i + 1, fitFunOut[i]->GetParameter(0));
0596     h_p0_eta->SetBinError(i + 1, fitFunOut[i]->GetParError(0));
0597   }
0598 
0599   CDBTTree* cdbttree1 = new CDBTTree(cdbFile);
0600   CDBTTree* cdbttree2 = new CDBTTree(cdbFile);
0601 
0602 
0603   float final_mass_target = target_pi0_mass;
0604 
0605   for (int i = 0; i < 96; i++)
0606   {
0607     for (int j = 0; j < 256; j++)
0608     {
0609       if (use_h_target_mass)
0610       {
0611         final_mass_target = h_target_mass->GetBinContent(i + 1);
0612       }
0613       float correction = final_mass_target / h_peak_eta->GetBinContent(i + 1);
0614       if (h_peak_eta->GetBinContent(i + 1) == 0)
0615       {
0616         correction = 0;
0617       }
0618       unsigned int key = TowerInfoDefs::encode_emcal(i, j);
0619       float val1 = cdbttree1->GetFloatValue(key, m_fieldname);
0620       cdbttree2->SetFloatValue(key, m_fieldname, val1 * correction);
0621     }
0622   }
0623 
0624   cdbttree2->Commit();
0625   cdbttree2->WriteCDBTTree();
0626   delete cdbttree2;
0627   delete cdbttree1;
0628 
0629   TFile* fit_out = new TFile(fitOutFile.c_str(), "recreate");
0630   fit_out->cd();
0631   for (auto& i : h_M_eta)
0632   {
0633     i->Write();
0634     delete i;
0635   }
0636   for (auto& i : fitFunOut)
0637   {
0638     i->Write();
0639     delete i;
0640   }
0641 
0642   h_p3_eta->Write();
0643   h_p4_eta->Write();
0644   h_p5_eta->Write();
0645   h_p6_eta->Write();
0646   h_p0_eta->Write();
0647   h_sigma_eta->Write();
0648   h_peak_eta->Write();
0649   fin->Close();
0650 
0651   std::cout << "finish fitting suc" << std::endl;
0652 
0653   return;
0654 }
0655 
0656 // for pi0 tbt fit
0657 void pi0EtaByEta::fitEtaPhiTowers(const std::string& infile, const std::string& fitOutFile, const std::string& cdbFile)
0658 {
0659   TFile* fin = new TFile(infile.c_str());
0660 
0661   std::cout << "getting hists" << std::endl;
0662 
0663   TH2* h_peak_tbt = new TH2F("h_peak_tbt", "", 96, 0, 96, 256, 0, 256);
0664   TH2* h_sigma_tbt = new TH2F("h_sigma_tbt", "", 96, 0, 96, 256, 0, 256);
0665   TH2* h_p3_tbt = new TH2F("h_p3_tbt", "", 96, 0, 96, 256, 0, 256);
0666   TH2* h_p4_tbt = new TH2F("h_p4_tbt", "", 96, 0, 96, 256, 0, 256);
0667   TH2* h_p5_tbt = new TH2F("h_p5_tbt", "", 96, 0, 96, 256, 0, 256);
0668   TH2* h_p6_tbt = new TH2F("h_p6_tbt", "", 96, 0, 96, 256, 0, 256);
0669   TH2* h_p0_tbt = new TH2F("h_p0_tbt", "", 96, 0, 96, 256, 0, 256);
0670   TH1* h_peak_tbt_1D = new TH1F("h_peak_tbt_1D", "", 24576, 0, 24576);
0671 
0672   if (!fin)
0673   {
0674     std::cout << "pi0EtaByEta::fitEtaPhiTowers null fin" << std::endl;
0675     exit(1);
0676   }
0677 
0678   TH1* h_M_tbt[96][256];
0679   TF1* fitFunOut[96][256];
0680 
0681   // creating output file
0682   TFile* fit_out = new TFile(fitOutFile.c_str(), "recreate");
0683 
0684   // we will load, fit and update one eta-bin a time and get into next eta-bin
0685   for (int ieta = 0; ieta < 96; ieta++)
0686   {
0687     std::cout << "fitting in etabin = " << ieta << std::endl;
0688     for (int j = 0; j < 256; j++)
0689     {
0690       std::string histoname = "h_mass_tbt_lt_" + std::to_string(ieta) + "_" + std::to_string(j);
0691       fin->GetObject(histoname.c_str(), h_M_tbt[ieta][j]);
0692 
0693       if (!h_M_tbt[ieta][j])
0694       {
0695         std::cout << "pi0EtaByEta::fitEtaPhiTowers null hist" << std::endl;
0696         gSystem->Exit(1);
0697         exit(1);
0698       }
0699  
0700       if (h_M_tbt[ieta][j]->GetEntries() == 0)
0701       {
0702         continue;
0703       }
0704 
0705       h_M_tbt[ieta][j]->Scale(1. / h_M_tbt[ieta][j]->Integral(), "width");
0706 
0707       fitFunOut[ieta][j] = fitHistogram(h_M_tbt[ieta][j]);
0708       std::string funcname = "f_pi0_tbt_" + std::to_string(ieta) + "_" + std::to_string(j);
0709       fitFunOut[ieta][j]->SetName(funcname.c_str());
0710 
0711       float mass_val_out = fitFunOut[ieta][j]->GetParameter(1);
0712       float mass_err_out = fitFunOut[ieta][j]->GetParError(1);
0713 
0714       if (std::isnan(h_M_tbt[ieta][j]->GetEntries()))
0715       {
0716         h_peak_tbt->SetBinContent(ieta + 1, j + 1, 0);
0717         h_peak_tbt->SetBinError(ieta + 1, j + 1, 0);
0718         continue;
0719       }
0720 
0721       h_peak_tbt->SetBinContent(ieta + 1, j + 1, mass_val_out);
0722       h_peak_tbt->SetBinError(ieta + 1, j + 1, mass_err_out);
0723 
0724       int towerID = TowerInfoDefs::decode_emcal(TowerInfoDefs::encode_emcal(ieta, j));
0725       h_peak_tbt_1D->SetBinContent(towerID + 1, mass_val_out);
0726       h_peak_tbt_1D->SetBinError(towerID + 1, mass_err_out);
0727 
0728       h_sigma_tbt->SetBinContent(ieta + 1, j + 1, fitFunOut[ieta][j]->GetParameter(2));
0729       h_sigma_tbt->SetBinError(ieta + 1, j + 1, fitFunOut[ieta][j]->GetParError(2));
0730 
0731       h_p3_tbt->SetBinContent(ieta + 1, j + 1, fitFunOut[ieta][j]->GetParameter(3));
0732       h_p3_tbt->SetBinError(ieta + 1, j + 1, fitFunOut[ieta][j]->GetParError(3));
0733 
0734       h_p4_tbt->SetBinContent(ieta + 1, j + 1, fitFunOut[ieta][j]->GetParameter(4));
0735       h_p4_tbt->SetBinError(ieta + 1, j + 1, fitFunOut[ieta][j]->GetParError(4));
0736 
0737       h_p5_tbt->SetBinContent(ieta + 1, j + 1, fitFunOut[ieta][j]->GetParameter(5));
0738       h_p5_tbt->SetBinError(ieta + 1, j + 1, fitFunOut[ieta][j]->GetParError(5));
0739 
0740       h_p6_tbt->SetBinContent(ieta + 1, j + 1, fitFunOut[ieta][j]->GetParameter(6));
0741       h_p6_tbt->SetBinError(ieta + 1, j + 1, fitFunOut[ieta][j]->GetParError(6));
0742 
0743       h_p0_tbt->SetBinContent(ieta + 1, j + 1, fitFunOut[ieta][j]->GetParameter(0));
0744       h_p0_tbt->SetBinError(ieta + 1, j + 1, fitFunOut[ieta][j]->GetParError(0));
0745 
0746     }  // fitting for all phi-towers in eta-bin
0747 
0748     fit_out->cd();
0749 
0750     // writing all towers and fit function in given etabin
0751     for (auto& _hist : h_M_tbt[ieta])
0752     {
0753       _hist->Write();
0754       delete _hist;
0755     }
0756 
0757     for (auto& _hist : fitFunOut[ieta])
0758     {
0759       _hist->Write();
0760       delete _hist;
0761     }
0762 
0763   }  // closing eta-bin loop
0764 
0765   // CDBTtree
0766   CDBTTree* cdbttree1 = new CDBTTree(cdbFile);
0767   CDBTTree* cdbttree2 = new CDBTTree(cdbFile);
0768 
0769   float final_mass_target = target_pi0_mass;
0770 
0771   for (int i = 0; i < 96; i++)
0772   {
0773     for (int j = 0; j < 256; j++)
0774     {
0775       if (use_h_target_mass)
0776       {
0777         final_mass_target = h_target_mass->GetBinContent(i + 1, j + 1);
0778       }
0779       float correction = final_mass_target / h_peak_tbt->GetBinContent(i + 1, j + 1);
0780       if (h_peak_tbt->GetBinContent(i + 1, j + 1) == 0)
0781       {
0782         correction = 0;
0783       }
0784       if (h_sigma_tbt->GetBinContent(i + 1, j + 1) > 0.040)
0785       {
0786         correction = 1;
0787       }
0788       unsigned int key = TowerInfoDefs::encode_emcal(i, j);
0789       float val1 = cdbttree1->GetFloatValue(key, m_fieldname);
0790       cdbttree2->SetFloatValue(key, m_fieldname, val1 * correction);
0791     }
0792   }
0793 
0794   // writing out CDBTtree
0795   cdbttree2->Commit();
0796   cdbttree2->WriteCDBTTree();
0797 
0798   delete cdbttree2;
0799   delete cdbttree1;
0800 
0801   // wrriting other histograms in output file
0802   h_p3_tbt->Write();
0803   h_p4_tbt->Write();
0804   h_p5_tbt->Write();
0805   h_p6_tbt->Write();
0806   h_p0_tbt->Write();
0807   h_sigma_tbt->Write();
0808   h_peak_tbt->Write();
0809   h_peak_tbt_1D->Write();
0810 
0811   // closing input and output files
0812   fin->Close();
0813   fit_out->Close();
0814 
0815   std::cout << "finish fitting suc" << std::endl;
0816 
0817   return;
0818 }
0819 
0820 bool pi0EtaByEta::checkOutput(const std::string& file)
0821 {
0822   TFile* fin = new TFile(file.c_str());
0823   TH1* h_peak_eta{nullptr};
0824   fin->GetObject("h_peak_eta", h_peak_eta);
0825 
0826   float final_mass_target = target_pi0_mass;
0827 
0828   int numNotConv = 0;
0829 
0830   for (int i = 0; i < 96; i++)
0831   {
0832     if (use_h_target_mass)
0833     {
0834       final_mass_target = h_target_mass->GetBinContent(i + 1);
0835     }
0836     float corr = 1.0 - (final_mass_target / h_peak_eta->GetBinContent(i + 1));
0837     if (h_peak_eta->GetBinContent(i + 1) == 0)
0838     {
0839       corr = 0;
0840     }
0841     std::cout << "err " << corr << std::endl;
0842     if (std::fabs(corr) > convLev)
0843     {
0844       numNotConv++;
0845     }
0846   }
0847 
0848   delete fin;
0849 
0850   if (numNotConv <= 1)
0851   {
0852     return true;
0853   }
0854   return false;
0855 }
0856 
0857 void pi0EtaByEta::set_massTargetHistFile(const std::string& file)
0858 {
0859   TFile* fin = new TFile(file.c_str());
0860   if (fin)
0861   {
0862     fin->GetObject("h_massTargetHist", h_target_mass);
0863   }
0864   else
0865   {
0866     std::cout << "pi0EtaByEta::set_massTargetHistFile  No mass file found" << std::endl;
0867     return;
0868   }
0869   if (h_target_mass)
0870   {
0871     use_h_target_mass = true;
0872     std::cout << "using target mass histogram" << std::endl;
0873   }
0874   else
0875   {
0876     std::cout << "pi0EtaByEta::set_massTargetHistFile  No mass hist found" << std::endl;
0877   }
0878   return;
0879 }
0880 
0881 // this will split one 3D Hist into 24576 1D hist that contain inv mass distribution for all towers
0882 void pi0EtaByEta::Split3DHist(const std::string& infile, const std::string& out_file)
0883 {
0884   // First we will copy all the content of input file to output file
0885   std::error_code ec;
0886   std::filesystem::copy(infile, out_file, ec);
0887   if (ec)
0888   {
0889     std::cout << "Error copying file from " << infile << " to " << out_file << std::endl;
0890     return;
0891   }
0892 
0893   // Then, we will open the output file after update
0894   TFile* ofile = new TFile(out_file.c_str(), "UPDATE");
0895   if (!ofile)
0896   {
0897     std::cout << "Error opening file: " << out_file << std::endl;
0898     return;
0899   }
0900 
0901   // We will extract 3D hist from updated output file
0902   ofile->GetObject("h_ieta_iphi_invmass", h_ieta_iphi_invmass);
0903   if (!h_ieta_iphi_invmass)
0904   {
0905     std::cout << "Error: 3D Histogram not found in file: " << out_file << std::endl;
0906     ofile->Close();
0907     return;
0908   }
0909 
0910   // Loop over ieta and iphi ranges (x and y axis)
0911   for (int bineta = 1; bineta <= 96; ++bineta)
0912   {
0913     for (int binphi = 1; binphi <= 256; ++binphi)
0914     {
0915       // Loop over third axis in 3D Hist and then fill it into 1D hist
0916       for (int binz = 1; binz <= h_ieta_iphi_invmass->GetNbinsZ(); ++binz)
0917       {
0918         float content = h_ieta_iphi_invmass->GetBinContent(bineta, binphi, binz);
0919         h_mass_tbt_lt[bineta - 1][binphi - 1]->SetBinContent(binz, content);
0920       }
0921     }
0922   }
0923 
0924   // Now we will update all the histogram in the output file
0925   ofile->cd();
0926 
0927   for (auto& i : h_mass_tbt_lt)
0928   {
0929     for (auto& j : i)
0930     {
0931       j->Write();
0932       delete j;
0933     }
0934   }
0935 
0936   ofile->Close();
0937 
0938   std::cout << "Splitting 3D Hist Completed." << std::endl;
0939 
0940   return;
0941 }