Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:16:10

0001 #include "Fun4AllHistoManager.h"
0002 
0003 #include "TDirectoryHelper.h"
0004 
0005 #include <phool/phool.h>
0006 #include <phool/recoConsts.h>
0007 
0008 #include <TFile.h>
0009 #include <TH1.h>
0010 #include <THnSparse.h>
0011 #include <TNamed.h>
0012 #include <TSystem.h>
0013 #include <TTree.h>
0014 
0015 #include <filesystem>
0016 #include <format>
0017 #include <iomanip>
0018 #include <iostream>
0019 #include <sstream>
0020 #include <utility>  // for pair
0021 
0022 Fun4AllHistoManager::Fun4AllHistoManager(const std::string &name)
0023   : Fun4AllBase(name)
0024 {
0025   return;
0026 }
0027 
0028 Fun4AllHistoManager::~Fun4AllHistoManager()
0029 {
0030   // the last file is closed by deleting the output manager, if we want to execute a script at the end
0031   // we have to run it here
0032   RunAfterClosing();
0033 
0034   while (Histo.begin() != Histo.end())
0035   {
0036     delete Histo.begin()->second;
0037     Histo.erase(Histo.begin());
0038   }
0039   return;
0040 }
0041 
0042 int Fun4AllHistoManager::RunAfterClosing()
0043 {
0044   unsigned int iret = 0;
0045 
0046   if (!m_RunAfterClosingScript.empty())
0047   {
0048     if (!std::filesystem::exists(m_RunAfterClosingScript))
0049     {
0050       std::cout << PHWHERE << "RunAfterClosing() closing script " << m_RunAfterClosingScript << " not found" << std::endl;
0051       return -1;
0052     }
0053     if (!((std::filesystem::status(m_RunAfterClosingScript).permissions() & std::filesystem::perms::owner_exec) == std::filesystem::perms::owner_exec))
0054     {
0055       std::cout << PHWHERE << "RunAfterClosing() closing script " << m_RunAfterClosingScript << " is not owner executable" << std::endl;
0056       return -1;
0057     }
0058     recoConsts *rc = recoConsts::instance();
0059     int runnumber = 0;
0060     std::string runseg;
0061     if (rc->FlagExist("RUNNUMBER") && m_dumpHistoSegments)
0062     {
0063       runnumber = rc->get_IntFlag("RUNNUMBER");
0064       runseg = std::format("-{:08}-{:05}.root",runnumber,m_CurrentSegment);
0065     }
0066     std::string fullcmd = m_RunAfterClosingScript + " " + m_outfilename + runseg + " " + m_ClosingArgs;
0067     if (Verbosity() > 1)
0068     {
0069       std::cout << PHWHERE << " running " << fullcmd << std::endl;
0070     }
0071     iret = gSystem->Exec(fullcmd.c_str());
0072   }
0073   if (iret)
0074   {
0075     iret = iret >> 8U;
0076   }
0077   return iret;
0078 }
0079 
0080 int Fun4AllHistoManager::dumpHistos(const std::string &filename, const std::string &openmode)
0081 {
0082   int iret = 0;
0083   if (!filename.empty())
0084   {
0085     m_outfilename = filename;
0086   }
0087   else
0088   {
0089     if (m_outfilename.empty())
0090     {
0091       recoConsts *rc = recoConsts::instance();
0092       std::ostringstream filnam;
0093       int runnumber = -1;
0094       if (rc->FlagExist("RUNNUMBER"))
0095       {
0096         runnumber = rc->get_IntFlag("RUNNUMBER");
0097       }
0098       // this will set the filename to the name of the manager
0099       // add the runnumber in the std 10 digit format and
0100       // end it with a .root extension
0101       filnam << Name() << "-"
0102              << std::setfill('0') << std::setw(10)
0103              << runnumber << ".root";
0104       m_outfilename = filnam.str();
0105     }
0106   }
0107   recoConsts *rc = recoConsts::instance();
0108   int runnumber = 0;
0109   std::string runseg;
0110   if (rc->FlagExist("RUNNUMBER") && m_dumpHistoSegments)
0111   {
0112     runnumber = rc->get_IntFlag("RUNNUMBER");
0113     runseg = std::format("-{:08}-{:05}.root",runnumber,m_CurrentSegment);
0114   }
0115 
0116   std::string theoutfile = m_outfilename + runseg;
0117   std::cout << "Fun4AllHistoManager::dumpHistos() Writing root file: " << theoutfile.c_str() << std::endl;
0118 
0119   const int compress = 9;
0120   std::ostringstream creator;
0121   creator << "Created by " << Name();
0122   TFile hfile(theoutfile.c_str(), openmode.c_str(), creator.str().c_str(), compress);
0123   if (!hfile.IsOpen())
0124   {
0125     std::cout << PHWHERE << " Could not open output file" << theoutfile.c_str() << std::endl;
0126     return -1;
0127   }
0128 
0129   std::map<const std::string, TNamed *>::const_iterator hiter;
0130   for (hiter = Histo.begin(); hiter != Histo.end(); ++hiter)
0131   {
0132     const std::string &hname = hiter->first;
0133     const TNamed *hptr = hiter->second;
0134     if (Verbosity() > 0)
0135     {
0136       std::cout << PHWHERE << " Saving histo "
0137                 << hname
0138                 << std::endl;
0139     }
0140 
0141     //  Decode the string to see if it wants a directory
0142     std::string::size_type pos = hname.find_last_of('/');
0143     std::string dirname;
0144     if (pos != std::string::npos)  // string::npos is the result if search unsuccessful
0145     {
0146       dirname = hname.substr(0, pos);
0147     }
0148     else
0149     {
0150       dirname = "";
0151     }
0152 
0153     if (Verbosity())
0154     {
0155       std::cout << " Histogram named " << hptr->GetName();
0156       std::cout << " key " << hname;
0157       if (!dirname.empty())
0158       {
0159         std::cout << " being saved to directory " << dirname;
0160       }
0161       std::cout << std::endl;
0162     }
0163 
0164     if (!dirname.empty())
0165     {
0166       TDirectoryHelper::mkdir(&hfile, dirname);
0167       hfile.cd(dirname.c_str());
0168     }
0169 
0170     if (hptr)
0171     {
0172       int byteswritten = hptr->Write();
0173       if (!byteswritten)
0174       {
0175         std::cout << PHWHERE << "Error saving histogram "
0176                   << hptr->GetName()
0177                   << std::endl;
0178         iret = -2;
0179       }
0180     }
0181     else
0182     {
0183       std::cout << PHWHERE << "dumpHistos : histogram "
0184                 << hname << " is a null pointer! Won't be saved."
0185                 << std::endl;
0186     }
0187   }
0188   hfile.Close();
0189   return iret;
0190 }
0191 
0192 bool Fun4AllHistoManager::registerHisto(TNamed *h1d, const int replace)
0193 {
0194   return registerHisto(h1d->GetName(), h1d, replace);
0195 }
0196 
0197 bool Fun4AllHistoManager::registerHisto(const std::string &hname, TNamed *h1d, const int replace)
0198 {
0199   std::map<const std::string, TNamed *>::const_iterator histoiter = Histo.find(hname);
0200   if (histoiter != Histo.end() && replace == 0)
0201   {
0202     std::cout << "Histogram " << hname << " already registered, I won't overwrite it" << std::endl;
0203     std::cout << "Use a different name and try again" << std::endl;
0204     return false;
0205   }
0206 
0207   std::string::size_type pos = hname.find_last_of('/');
0208   std::string histoname = hname;
0209   if (pos != std::string::npos)  // okay someone wants damn TDirectories
0210   {
0211     histoname = hname.substr(pos + 1);
0212   }
0213   if (Verbosity() > 1)
0214   {
0215     if (histoname != h1d->GetName())
0216     {
0217       std::cout << PHWHERE << "Histogram " << h1d->GetName()
0218                 << " at " << h1d << " renamed to " << histoname << std::endl;
0219     }
0220   }
0221   // this one did some very ugly mutilation to a const char *
0222   // using a string seems to avoid the damage
0223   h1d->SetName(histoname.c_str());
0224   Histo[hname] = h1d;
0225 
0226   // reset directory for TTree
0227   if (h1d->InheritsFrom("TTree"))
0228   {
0229     static_cast<TTree *>(h1d)->SetDirectory(nullptr); // NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
0230   }
0231 
0232   // For histograms, enforce error calculation and propagation
0233   if (h1d->InheritsFrom("TH1"))
0234   {
0235     static_cast<TH1 *>(h1d)->Sumw2();// NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
0236   }
0237 
0238   return true;
0239 }
0240 
0241 int Fun4AllHistoManager::isHistoRegistered(const std::string &name) const
0242 {
0243   std::map<const std::string, TNamed *>::const_iterator histoiter = Histo.find(name);
0244   if (histoiter != Histo.end())
0245   {
0246     return 1;
0247   }
0248   return 0;
0249 }
0250 
0251 TNamed *
0252 Fun4AllHistoManager::getHisto(const unsigned int ihisto) const
0253 {
0254   std::map<const std::string, TNamed *>::const_iterator histoiter = Histo.begin();
0255   unsigned int size = Histo.size();
0256   if (Verbosity() > 3)
0257   {
0258     std::cout << "Map contains " << size << " Elements" << std::endl;
0259   }
0260   if (ihisto < size)
0261   {
0262     for (unsigned int i = 0; i < ihisto; i++)
0263     {
0264       ++histoiter;
0265     }
0266     return histoiter->second;
0267   }
0268 
0269   std::cout << "Fun4AllHistoManager::getHisto: ERROR Invalid histogram number: "
0270             << ihisto << ", maximum number is " << size << std::endl;
0271 
0272   return nullptr;
0273 }
0274 
0275 std::string
0276 Fun4AllHistoManager::getHistoName(const unsigned int ihisto) const
0277 {
0278   std::map<const std::string, TNamed *>::const_iterator histoiter = Histo.begin();
0279   unsigned int size = Histo.size();
0280   if (Verbosity() > 3)
0281   {
0282     std::cout << "Map contains " << size << " Elements" << std::endl;
0283   }
0284   if (ihisto < size)
0285   {
0286     for (unsigned int i = 0; i < ihisto; i++)
0287     {
0288       ++histoiter;
0289     }
0290     return histoiter->first;
0291   }
0292 
0293   std::cout << "Fun4AllHistoManager::getHisto: ERROR Invalid histogram number: "
0294             << ihisto << ", maximum number is " << size << std::endl;
0295 
0296   return "";
0297 }
0298 
0299 TNamed *
0300 Fun4AllHistoManager::getHisto(const std::string &hname) const
0301 {
0302   std::map<const std::string, TNamed *>::const_iterator histoiter = Histo.find(hname);
0303   if (histoiter != Histo.end())
0304   {
0305     return histoiter->second;
0306   }
0307   std::cout << "Fun4AllHistoManager::getHisto: ERROR Unknown Histogram " << hname
0308             << ", The following are implemented: " << std::endl;
0309   Print("ALL");
0310   return nullptr;
0311 }
0312 
0313 void Fun4AllHistoManager::Print(const std::string &what) const
0314 {
0315   if (what == "ALL" || what == "HISTOS")
0316   {
0317     // loop over the map and print out the content (name and location in memory)
0318     std::cout << "--------------------------------------" << std::endl
0319               << std::endl;
0320     std::cout << "List of Histos in Fun4AllHistoManager "
0321               << Name() << ":" << std::endl;
0322 
0323     std::map<const std::string, TNamed *>::const_iterator hiter;
0324     for (hiter = Histo.begin(); hiter != Histo.end(); ++hiter)
0325     {
0326       std::cout << hiter->first << " is " << hiter->second << std::endl;
0327     }
0328     std::cout << std::endl;
0329   }
0330   return;
0331 }
0332 
0333 void Fun4AllHistoManager::Reset()
0334 {
0335   std::map<const std::string, TNamed *>::const_iterator hiter;
0336   for (hiter = Histo.begin(); hiter != Histo.end(); ++hiter)
0337   {
0338     TNamed *h = hiter->second;
0339     if (h->InheritsFrom("TH1"))
0340     {
0341       (dynamic_cast<TH1 *>(h))->Reset();
0342     }
0343     else if (h->InheritsFrom("THnSparse"))
0344     {
0345       (dynamic_cast<THnSparse *>(h))->Reset();
0346     }
0347   }
0348   return;
0349 }