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
0031
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
0099
0100
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
0142 std::string::size_type pos = hname.find_last_of('/');
0143 std::string dirname;
0144 if (pos != std::string::npos)
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)
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
0222
0223 h1d->SetName(histoname.c_str());
0224 Histo[hname] = h1d;
0225
0226
0227 if (h1d->InheritsFrom("TTree"))
0228 {
0229 static_cast<TTree *>(h1d)->SetDirectory(nullptr);
0230 }
0231
0232
0233 if (h1d->InheritsFrom("TH1"))
0234 {
0235 static_cast<TH1 *>(h1d)->Sumw2();
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
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 }