From 885023ef7a0a5c8b411bf6832664be70145eda8e Mon Sep 17 00:00:00 2001 From: Michael Mendenhall Date: Tue, 1 Mar 2016 08:25:13 -0500 Subject: [PATCH] Separate sub-TDirectories for plugin outputs --- ROOTUtils/OutputManager.cc | 38 ++++++++++++++++++-------------- ROOTUtils/OutputManager.hh | 26 +++++++++++----------- ROOTUtils/PluginSaver.cc | 7 +++--- ROOTUtils/PluginSaver.hh | 20 ++++++++--------- ROOTUtils/SegmentSaver.cc | 44 +++++++++++++++++++++----------------- ROOTUtils/SegmentSaver.hh | 1 + ROOTUtils/TObjCollector.cc | 9 ++++---- ROOTUtils/TObjCollector.hh | 6 +++--- 8 files changed, 81 insertions(+), 70 deletions(-) diff --git a/ROOTUtils/OutputManager.cc b/ROOTUtils/OutputManager.cc index 2c7dd80..9f7312b 100644 --- a/ROOTUtils/OutputManager.cc +++ b/ROOTUtils/OutputManager.cc @@ -21,13 +21,16 @@ #include "OutputManager.hh" #include "PathUtils.hh" +#include +#include #include #include +#include bool OutputManager::squelchAllPrinting = false; OutputManager::OutputManager(string nm, string bp): -rootOut(NULL), defaultCanvas(new TCanvas()), +defaultCanvas(new TCanvas()), parent(NULL), name(nm) { TH1::AddDirectory(kFALSE); // set up output canvas @@ -39,7 +42,7 @@ parent(NULL), name(nm) { } OutputManager::OutputManager(string nm, OutputManager* pnt): -rootOut(NULL), defaultCanvas(NULL), parent(pnt), name(nm) { +defaultCanvas(NULL), parent(pnt), name(nm) { TH1::AddDirectory(kFALSE); if(parent) { defaultCanvas = parent->defaultCanvas; @@ -47,39 +50,42 @@ rootOut(NULL), defaultCanvas(NULL), parent(pnt), name(nm) { } } -void OutputManager::openOutfile() { - if(rootOut) { rootOut->Close(); } - makePath(rootPath); - rootOut = new TFile((rootPath+"/"+name+".root").c_str(),"RECREATE"); - rootOut->cd(); +TDirectory* OutputManager::writeItems(TDirectory* d) { + if(!d) d = gDirectory; + else d = d->mkdir(name.c_str()); + assert(d); + return TObjCollector::writeItems(d); } -void OutputManager::writeROOT() { +void OutputManager::writeROOT(TDirectory* parentDir) { printf("\n--------- Building output .root file... ----------\n"); - if(!rootOut) openOutfile(); - rootOut->cd(); - writeItems(); + TFile* rootOut = NULL; + if(parentDir) writeItems(parentDir); + else { + makePath(rootPath); + string outfname = rootPath+"/"+name+".root"; + printf("Writing to '%s'\n", outfname.c_str()); + rootOut = new TFile(outfname.c_str(),"RECREATE"); + rootOut->cd(); + writeItems(NULL); + } clearItems(); - rootOut->Close(); - rootOut = NULL; + delete rootOut; printf("--------- Done. ----------\n"); } TH1F* OutputManager::registeredTH1F(string hname, string htitle, unsigned int nbins, float x0, float x1) { - if(rootOut) rootOut->cd(); TH1F* h = new TH1F(hname.c_str(),htitle.c_str(),nbins,x0,x1); return (TH1F*)addObject(h); } TH1D* OutputManager::registeredTH1D(string hname, string htitle, unsigned int nbins, float x0, float x1) { - if(rootOut) rootOut->cd(); TH1D* h = new TH1D(hname.c_str(),htitle.c_str(),nbins,x0,x1); return (TH1D*)addObject(h); } TH2F* OutputManager::registeredTH2F(string hname, string htitle, unsigned int nbinsx, float x0, float x1, unsigned int nbinsy, float y0, float y1) { - if(rootOut) rootOut->cd(); return (TH2F*)addObject(new TH2F(hname.c_str(),htitle.c_str(),nbinsx,x0,x1,nbinsy,y0,y1)); } diff --git a/ROOTUtils/OutputManager.hh b/ROOTUtils/OutputManager.hh index c7664ae..35b7101 100644 --- a/ROOTUtils/OutputManager.hh +++ b/ROOTUtils/OutputManager.hh @@ -47,7 +47,6 @@ public: /// destructor virtual ~OutputManager() { clearItems(); - if(rootOut) rootOut->Close(); if(!parent) delete defaultCanvas; } @@ -59,20 +58,19 @@ public: TH2F* registeredTH2F(string hname, string htitle, unsigned int nbinsx, float x0, float x1, unsigned int nbinsy, float y0, float y1); /// print current canvas virtual void printCanvas(string fname, string suffix=".pdf") const; - - /// open output ROOT file for writing - virtual void openOutfile(); - /// write output ROOT file; WARNING: THIS DELETES ALL REGISTERED ITEMS; do last if you reference these! - void writeROOT(); - TFile* rootOut; ///< ROOT file output - TCanvas* defaultCanvas; ///< canvas for drawing plots - OutputManager* parent; ///< parent output manager - string basePath; ///< general output path - string plotPath; ///< specific output path for plots - string dataPath; ///< specific output path for output data - string rootPath; ///< specific output path for ROOT files - string name; ///< name for this subsystem + /// write items to currently open directory, or specified + TDirectory* writeItems(TDirectory* d = NULL) override; + /// write output ROOT file, or to new directory within parent; WARNING: THIS DELETES ALL REGISTERED ITEMS; do last if you reference these! + void writeROOT(TDirectory* parentDir = NULL); + + TCanvas* defaultCanvas; ///< canvas for drawing plots + OutputManager* parent = NULL; ///< parent output manager + string basePath; ///< general output path + string plotPath; ///< specific output path for plots + string dataPath; ///< specific output path for output data + string rootPath; ///< specific output path for ROOT files + string name; ///< name for this subsystem static bool squelchAllPrinting; ///< whether to cancel all printCanvas output }; diff --git a/ROOTUtils/PluginSaver.cc b/ROOTUtils/PluginSaver.cc index 8b174c9..4da407d 100644 --- a/ROOTUtils/PluginSaver.cc +++ b/ROOTUtils/PluginSaver.cc @@ -122,12 +122,13 @@ void PluginSaver::calculateResults() { kv.second->thePlugin->calculateResults(); } -void PluginSaver::writeItems() { - SegmentSaver::writeItems(); +TDirectory* PluginSaver::writeItems(TDirectory* d) { + d = SegmentSaver::writeItems(d); printf("Writing plugins '%s'\n", filePlugins->String().Data()); for(auto& kv: myBuilders) if(kv.second->thePlugin) - kv.second->thePlugin->writeItems(); + kv.second->thePlugin->writeItems(d); + return d; } void PluginSaver::clearItems() { diff --git a/ROOTUtils/PluginSaver.hh b/ROOTUtils/PluginSaver.hh index 1dc66e0..7909136 100644 --- a/ROOTUtils/PluginSaver.hh +++ b/ROOTUtils/PluginSaver.hh @@ -31,24 +31,24 @@ public: SegmentSaver* getPlugin(const string& nm) const; /// zero out all saved histograms - virtual void zeroSavedHists() override; + void zeroSavedHists() override; /// scale all saved histograms by a factor - virtual void scaleData(double s) override; + void scaleData(double s) override; /// perform normalization on all histograms (e.g. conversion to differential rates); should only be done once! - virtual void normalize() override; + void normalize() override; /// add histograms from another SegmentSaver of the same type - virtual void addSegment(const SegmentSaver& S, double sc = 1.) override; + void addSegment(const SegmentSaver& S, double sc = 1.) override; /// virtual routine for generating output plots - virtual void makePlots() override; + void makePlots() override; /// virtual routine for generating calculated hists - virtual void calculateResults() override; + void calculateResults() override; /// virtual routine for comparing to other analyzers (of this type or NULL; meaning implementation-dependent) - virtual void compare(const vector& v) override; + void compare(const vector& v) override; - /// write items to file - virtual void writeItems() override; + /// write items to current directory or subdirectory of provided + TDirectory* writeItems(TDirectory* d = NULL) override; /// clear (delete) items - virtual void clearItems() override; + void clearItems() override; protected: /// build plugins appropriate for input file; call in subclass after setting up myBuilders diff --git a/ROOTUtils/SegmentSaver.cc b/ROOTUtils/SegmentSaver.cc index fd534a9..dc0a199 100644 --- a/ROOTUtils/SegmentSaver.cc +++ b/ROOTUtils/SegmentSaver.cc @@ -24,15 +24,37 @@ #include "SMExcept.hh" #include +SegmentSaver::SegmentSaver(OutputManager* pnt, const string& nm, const string& inflName): +OutputManager(nm,pnt), ignoreMissingHistos(false), inflname(inflName), isCalculated(false), inflAge(0) { + // open file to load existing data + fIn = (inflname.size())?(new TFile(inflname.c_str(),"READ")) : NULL; + smassert(!fIn || !fIn->IsZombie(),"unreadable_file"); + if(fIn) { + dirIn = fIn->GetDirectory(""); + inflAge = fileAge(inflname); + printf("Loading data from %s [%.1f hours old]...\n",inflname.c_str(),inflAge/3600.); + } + auto PSS = dynamic_cast(pnt); + if(PSS && PSS->dirIn) dirIn = PSS->dirIn->GetDirectory(nm.c_str()); +} + +SegmentSaver::~SegmentSaver() { + if(fIn) { + fIn->Close(); + delete fIn; + } +} + void resetZaxis(TH1* o) { TObject* a = o->GetListOfFunctions()->FindObject("palette"); if(a) o->GetListOfFunctions()->Remove(a); } TObject* SegmentSaver::tryLoad(const string& oname) { - if(!fIn) return NULL; + if(!fIn && !dirIn) return NULL; TObject* o = NULL; - fIn->GetObject(oname.c_str(),o); + if(dirIn) dirIn->GetObject(oname.c_str(),o); // first try in my directory + if(!o && fIn) fIn->GetObject(oname.c_str(),o); // fall back to file base for backwards compatibility if(!o) { if(ignoreMissingHistos) { printf("Warning: missing object '%s' in '%s'\n",oname.c_str(),inflname.c_str()); @@ -102,24 +124,6 @@ TCumulative* SegmentSaver::registerCumulative(const string& onm, const TCumulati return c; } -SegmentSaver::SegmentSaver(OutputManager* pnt, const string& nm, const string& inflName): -OutputManager(nm,pnt), ignoreMissingHistos(false), inflname(inflName), isCalculated(false), inflAge(0) { - // open file to load existing data - fIn = (inflname.size())?(new TFile(inflname.c_str(),"READ")):NULL; - smassert(!fIn || !fIn->IsZombie(),"unreadable_file"); - if(fIn) { - inflAge = fileAge(inflname); - printf("Loading data from %s [%.1f hours old]...\n",inflname.c_str(),inflAge/3600.); - } -} - -SegmentSaver::~SegmentSaver() { - if(fIn) { - fIn->Close(); - delete fIn; - } -} - TH1* SegmentSaver::getSavedHist(const string& hname) { auto it = saveHists.find(hname); smassert(it != saveHists.end()); diff --git a/ROOTUtils/SegmentSaver.hh b/ROOTUtils/SegmentSaver.hh index e43682b..2957ce7 100644 --- a/ROOTUtils/SegmentSaver.hh +++ b/ROOTUtils/SegmentSaver.hh @@ -102,6 +102,7 @@ public: virtual void compare(const vector&) { } TFile* fIn; ///< input file to read in histograms from + TDirectory* dirIn = NULL; ///< particular sub-directory for reading histograms string inflname; ///< where to look for input file bool isCalculated; ///< flag for whether calculation step has been completed diff --git a/ROOTUtils/TObjCollector.cc b/ROOTUtils/TObjCollector.cc index fea1c6d..259bbb2 100644 --- a/ROOTUtils/TObjCollector.cc +++ b/ROOTUtils/TObjCollector.cc @@ -8,12 +8,13 @@ #include "TObjCollector.hh" #include -void TObjCollector::writeItems() { - //printf("Saving registered objects..."); - //fflush(stdout); +TDirectory* TObjCollector::writeItems(TDirectory* d) { + if(!d) d = gDirectory; + assert(d); + d->cd(); for(auto i: namedItems) i->Write(); for(auto const& kv: anonItems) kv.second->Write(kv.first.c_str()); - //printf(" Done.\n"); + return d; } void TObjCollector::clearItems() { diff --git a/ROOTUtils/TObjCollector.hh b/ROOTUtils/TObjCollector.hh index 246c4de..1c9a8b8 100644 --- a/ROOTUtils/TObjCollector.hh +++ b/ROOTUtils/TObjCollector.hh @@ -8,9 +8,9 @@ #ifndef TOBJCOLLECTOR_HH #define TOBJCOLLECTOR_HH -#include #include #include +#include #include using std::string; @@ -25,8 +25,8 @@ public: /// destructor virtual ~TObjCollector() { clearItems(); } - /// write items to file - virtual void writeItems(); + /// write items to currently open directory, or specified; return directory written to + virtual TDirectory* writeItems(TDirectory* d = NULL); /// clear (delete) items virtual void clearItems(); /// register a named ROOT object for output (and eventual deletion)