modified: Armory/HistPlotter.h
modified: TrackRecon.C made changes to account for frequent crashes due to the number of histograms. New changes allow for flsuhing of data to histograms every n events modified: run_27Al.sh
This commit is contained in:
parent
a292695a4d
commit
14999546b7
|
|
@ -20,37 +20,52 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <TGraphErrors.h>
|
#include <TGraphErrors.h>
|
||||||
|
|
||||||
class HistPlotter {
|
class HistPlotter
|
||||||
|
{
|
||||||
private:
|
private:
|
||||||
long long barrier_count, barrier_limit; //meant to keep track of how often to call FillN() on histograms
|
long long barrier_count, barrier_limit; // meant to keep track of how often to call FillN() on histograms
|
||||||
enum {TFILE, TMEMFILE} filetype;
|
enum
|
||||||
std::map<std::string,TObject*> oMap; //!< Maps std::string to all TH1, TH2 objects in the class
|
{
|
||||||
std::unordered_map<std::string,TObject*> cutsMap; //!< Maps std::string to TCutG objects held by the class
|
TFILE,
|
||||||
std::set<std::string> folderList; //!< List of all folder names used to nest objects
|
TMEMFILE
|
||||||
std::unordered_map<TObject*,std::string> foldersForObjects; //!< Map that returns the folder corresponding to the object whose pointer is specified
|
} filetype;
|
||||||
TFile *ofile=nullptr; //!< TFile pointer for the output file
|
std::map<std::string, TObject *> oMap; //!< Maps std::string to all TH1, TH2 objects in the class
|
||||||
TMemFile *omfile=nullptr; //!< TFile pointer for the output memfile
|
std::unordered_map<std::string, TObject *> cutsMap; //!< Maps std::string to TCutG objects held by the class
|
||||||
|
std::set<std::string> folderList; //!< List of all folder names used to nest objects
|
||||||
|
std::unordered_map<TObject *, std::string> foldersForObjects; //!< Map that returns the folder corresponding to the object whose pointer is specified
|
||||||
|
TFile *ofile = nullptr; //!< TFile pointer for the output file
|
||||||
|
TMemFile *omfile = nullptr; //!< TFile pointer for the output memfile
|
||||||
|
|
||||||
//Caches to permit FillN() calls
|
// Caches to permit FillN() calls
|
||||||
std::map<std::string, std::vector<double>> onedimcache;
|
std::map<std::string, std::vector<double>> onedimcache;
|
||||||
std::map<std::string, std::pair<std::vector<double>, std::vector<double>>> twodimcache;
|
std::map<std::string, std::pair<std::vector<double>, std::vector<double>>> twodimcache;
|
||||||
inline void FillN_All_Histograms();
|
inline void FillN_All_Histograms();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HistPlotter(std::string outfile, std::string type);
|
HistPlotter(std::string outfile, std::string type);
|
||||||
inline void FlushToDisk(int integral); //!< Writes all objects to file before closing, nesting objects in folders as is found necessary
|
inline void FlushToDisk(int integral); //!< Writes all objects to file before closing, nesting objects in folders as is found necessary
|
||||||
inline void PrintObjects(); //!< Dump objects to std::cout for inspection
|
inline void PrintObjects(); //!< Dump objects to std::cout for inspection
|
||||||
inline void ReadCuts(std::string);
|
inline void ReadCuts(std::string);
|
||||||
inline TCutG* FindCut(std::string cut) {
|
inline TCutG *FindCut(std::string cut)
|
||||||
return static_cast<TCutG*>(cutsMap.at(cut));
|
{
|
||||||
|
return static_cast<TCutG *>(cutsMap.at(cut));
|
||||||
}
|
}
|
||||||
inline void set_barrier_limit(long long limit) { barrier_limit = limit; }
|
inline void set_barrier_limit(long long limit) { barrier_limit = limit; }
|
||||||
inline void barrier_increment() {
|
inline void barrier_increment()
|
||||||
|
{
|
||||||
barrier_count++;
|
barrier_count++;
|
||||||
if(barrier_count == barrier_limit) {
|
if (barrier_count == barrier_limit)
|
||||||
|
{
|
||||||
FillN_All_Histograms();
|
FillN_All_Histograms();
|
||||||
barrier_count=0;
|
barrier_count = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void force_flush_caches()
|
||||||
|
{
|
||||||
|
FillN_All_Histograms();
|
||||||
|
barrier_count = 0;
|
||||||
|
}
|
||||||
/*! \fn void FindCut()
|
/*! \fn void FindCut()
|
||||||
\brief
|
\brief
|
||||||
- Searches for a cut by name 'cut' in the internal list of cuts 'cutsMap'. Ugly fails (via unresolved at()) if such a cut isn't found.
|
- Searches for a cut by name 'cut' in the internal list of cuts 'cutsMap'. Ugly fails (via unresolved at()) if such a cut isn't found.
|
||||||
|
|
@ -58,109 +73,129 @@ public:
|
||||||
\return Pointer to the TCutG object that matches the name. Very useful to use this as plotter.FindCut("protonbarrelpid")->IsInside(deltaE, E) for instance.
|
\return Pointer to the TCutG object that matches the name. Very useful to use this as plotter.FindCut("protonbarrelpid")->IsInside(deltaE, E) for instance.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
inline void SetNewTitle(std::string name, std::string title) {
|
inline void SetNewTitle(std::string name, std::string title)
|
||||||
auto result = oMap.find(name); //result is an iterator
|
{
|
||||||
if(result==oMap.end()) return; //no warnings, could be changed in future
|
auto result = oMap.find(name); // result is an iterator
|
||||||
|
if (result == oMap.end())
|
||||||
|
return; // no warnings, could be changed in future
|
||||||
else
|
else
|
||||||
static_cast<TNamed*>(oMap.at(name))->SetTitle(title.c_str()); // set new title
|
static_cast<TNamed *>(oMap.at(name))->SetTitle(title.c_str()); // set new title
|
||||||
}
|
}
|
||||||
|
|
||||||
//Smart functions that create a new histogram if it doesn't exist.
|
// Smart functions that create a new histogram if it doesn't exist.
|
||||||
inline void FillGraph(const std::string &name, float valuex, float valuey, float errx=0, float erry=0);
|
inline void FillGraph(const std::string &name, float valuex, float valuey, float errx = 0, float erry = 0);
|
||||||
inline void Fill1D(const std::string& name,int nbinsx, float xlow, float xhigh, float value);
|
inline void Fill1D(const std::string &name, int nbinsx, float xlow, float xhigh, float value);
|
||||||
inline void Fill2D(const std::string& name,int nbinsx, float xlow, float xhigh
|
inline void Fill2D(const std::string &name, int nbinsx, float xlow, float xhigh, int nbinsy, float ylow, float yhigh, float valuex, float valuey);
|
||||||
,int nbinsy, float ylow, float yhigh, float valuex, float valuey);
|
inline void Fill1D(const std::string &name, int nbinsx, float xlow, float xhigh, float value, const std::string &folder);
|
||||||
inline void Fill1D(const std::string& name,int nbinsx, float xlow, float xhigh, float value, const std::string& folder);
|
inline void Fill2D(const std::string &name, int nbinsx, float xlow, float xhigh, int nbinsy, float ylow, float yhigh, float valuex, float valuey, const std::string &folder);
|
||||||
inline void Fill2D(const std::string& name,int nbinsx, float xlow, float xhigh
|
// TObject* findObject(std::string key);
|
||||||
,int nbinsy, float ylow, float yhigh, float valuex, float valuey, const std::string& folder);
|
|
||||||
//TObject* findObject(std::string key);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HistPlotter::HistPlotter(std::string outfile, std::string type="") {
|
HistPlotter::HistPlotter(std::string outfile, std::string type = "")
|
||||||
|
{
|
||||||
/*!
|
/*!
|
||||||
\brief Constructor. Opens a TFile instance with the specified filename
|
\brief Constructor. Opens a TFile instance with the specified filename
|
||||||
\param outfile : std::string that holds the desired output ROOT filename
|
\param outfile : std::string that holds the desired output ROOT filename
|
||||||
\return None
|
\return None
|
||||||
*/
|
*/
|
||||||
if(type=="" || type == "TFILE") {
|
if (type == "" || type == "TFILE")
|
||||||
ofile = new TFile(outfile.c_str(),"recreate");
|
{
|
||||||
filetype = TFILE;
|
ofile = new TFile(outfile.c_str(), "recreate");
|
||||||
} else if(type =="TMEMFILE") {
|
|
||||||
omfile = new TMemFile(outfile.c_str(),"recreate");
|
|
||||||
filetype=TMEMFILE;
|
|
||||||
} else {
|
|
||||||
std::cout << "Unknown type "<< type << " specified for HistPlotter (use \"TFILE\" or \"TMEMFILE\"), using default \"TFILE\" " << std::endl;
|
|
||||||
ofile = new TFile(outfile.c_str(),"recreate");
|
|
||||||
filetype = TFILE;
|
filetype = TFILE;
|
||||||
}
|
}
|
||||||
barrier_count=0;
|
else if (type == "TMEMFILE")
|
||||||
barrier_limit=1000;
|
{
|
||||||
|
omfile = new TMemFile(outfile.c_str(), "recreate");
|
||||||
|
filetype = TMEMFILE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Unknown type " << type << " specified for HistPlotter (use \"TFILE\" or \"TMEMFILE\"), using default \"TFILE\" " << std::endl;
|
||||||
|
ofile = new TFile(outfile.c_str(), "recreate");
|
||||||
|
filetype = TFILE;
|
||||||
|
}
|
||||||
|
barrier_count = 0;
|
||||||
|
barrier_limit = 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistPlotter::FillN_All_Histograms() {
|
void HistPlotter::FillN_All_Histograms()
|
||||||
for(auto it=oMap.begin(); it!=oMap.end(); it++ ) {
|
{
|
||||||
//it->first is std::string 'name', it->second is the TObject
|
for (auto it = oMap.begin(); it != oMap.end(); it++)
|
||||||
if(it->second->InheritsFrom("TH1F")) {
|
{
|
||||||
//FillN(size, array-of-doubles, array-of-weights); //we set array-of-weights to (1,1,1,.. (size)
|
// it->first is std::string 'name', it->second is the TObject
|
||||||
static_cast<TH1F*>(it->second)->FillN(onedimcache[it->first].size(), //size
|
if (it->second->InheritsFrom("TH1F"))
|
||||||
onedimcache[it->first].data(), //array
|
{
|
||||||
std::vector<double>(onedimcache[it->first].size(),1.0).data()); //weight of ones
|
// FillN(size, array-of-doubles, array-of-weights); //we set array-of-weights to (1,1,1,.. (size)
|
||||||
|
static_cast<TH1F *>(it->second)->FillN(onedimcache[it->first].size(), // size
|
||||||
|
onedimcache[it->first].data(), // array
|
||||||
|
std::vector<double>(onedimcache[it->first].size(), 1.0).data()); // weight of ones
|
||||||
onedimcache[it->first].clear();
|
onedimcache[it->first].clear();
|
||||||
} else if(it->second->InheritsFrom("TH2F")) {
|
}
|
||||||
//FillN(size, array-of-doubles, array-of-weights); //we set array-of-weights to (1,1,1,.. (size))
|
else if (it->second->InheritsFrom("TH2F"))
|
||||||
static_cast<TH2F*>(it->second)->FillN(twodimcache[it->first].first.size(), //size
|
{
|
||||||
twodimcache[it->first].first.data(), //x array
|
// FillN(size, array-of-doubles, array-of-weights); //we set array-of-weights to (1,1,1,.. (size))
|
||||||
twodimcache[it->first].second.data(), //y array
|
static_cast<TH2F *>(it->second)->FillN(twodimcache[it->first].first.size(), // size
|
||||||
std::vector<double>(twodimcache[it->first].first.size(),1.0).data()); //weight of ones
|
twodimcache[it->first].first.data(), // x array
|
||||||
twodimcache[it->first].first.clear();
|
twodimcache[it->first].second.data(), // y array
|
||||||
twodimcache[it->first].second.clear();
|
std::vector<double>(twodimcache[it->first].first.size(), 1.0).data()); // weight of ones
|
||||||
|
twodimcache[it->first].first.clear();
|
||||||
|
twodimcache[it->first].second.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout << "." << std::endl;
|
std::cout << "." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistPlotter::FlushToDisk(int min_integral=0) {
|
void HistPlotter::FlushToDisk(int min_integral = 0)
|
||||||
|
{
|
||||||
/*! \fn void FlushToDisk()
|
/*! \fn void FlushToDisk()
|
||||||
\brief Function that can be used at any point to exit smoothly by saving all ROOT objects in memory
|
\brief Function that can be used at any point to exit smoothly by saving all ROOT objects in memory
|
||||||
to the output file before closing it. Obeys the binding of histograms to separate folders, if so specified.
|
to the output file before closing it. Obeys the binding of histograms to separate folders, if so specified.
|
||||||
\return No return -- void
|
\return No return -- void
|
||||||
*/
|
*/
|
||||||
if(filetype==TMEMFILE && omfile) {
|
if (filetype == TMEMFILE && omfile)
|
||||||
|
{
|
||||||
std::cout << "Not flushing a TMemfile .. exiting .." << std::endl;
|
std::cout << "Not flushing a TMemfile .. exiting .." << std::endl;
|
||||||
delete omfile;
|
delete omfile;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(ofile->IsZombie() || !ofile) {
|
if (ofile->IsZombie() || !ofile)
|
||||||
|
{
|
||||||
std::cerr << "Output file is zombie, finishing up without writing to disk!" << std::endl;
|
std::cerr << "Output file is zombie, finishing up without writing to disk!" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
FillN_All_Histograms();
|
FillN_All_Histograms();
|
||||||
for(auto it=oMap.begin(); it!=oMap.end(); it++ ) {
|
for (auto it = oMap.begin(); it != oMap.end(); it++)
|
||||||
//omap maps: name(first) to object address(second).
|
{
|
||||||
// foldersForObjects maps: object address(first) to foldername(second)
|
// omap maps: name(first) to object address(second).
|
||||||
auto result = foldersForObjects.find(it->second); //returns <TObject* histogram,std::string foldername> pair if found
|
// foldersForObjects maps: object address(first) to foldername(second)
|
||||||
if(result!=foldersForObjects.end()) { //we try to create folder if needed and cd to it
|
auto result = foldersForObjects.find(it->second); // returns <TObject* histogram,std::string foldername> pair if found
|
||||||
ofile->mkdir(result->second.c_str(),"",kTRUE); // args: name, title, returnExistingDirectory
|
if (result != foldersForObjects.end())
|
||||||
|
{ // we try to create folder if needed and cd to it
|
||||||
|
ofile->mkdir(result->second.c_str(), "", kTRUE); // args: name, title, returnExistingDirectory
|
||||||
ofile->cd(result->second.c_str());
|
ofile->cd(result->second.c_str());
|
||||||
} else {
|
|
||||||
ofile->cd(); //toplevel for all default histograms. Default setting
|
|
||||||
}
|
}
|
||||||
if(((TH1F*)it->second)->Integral()>min_integral)
|
else
|
||||||
it->second->Write();
|
{
|
||||||
|
ofile->cd(); // toplevel for all default histograms. Default setting
|
||||||
|
}
|
||||||
|
if (((TH1F *)it->second)->Integral() > min_integral)
|
||||||
|
it->second->Write();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Create a directory for all cuts, and save all cuts in them
|
// Create a directory for all cuts, and save all cuts in them
|
||||||
ofile->mkdir("gCUTS","",kTRUE);
|
ofile->mkdir("gCUTS", "", kTRUE);
|
||||||
ofile->cd("gCUTS");
|
ofile->cd("gCUTS");
|
||||||
for(auto it=cutsMap.begin(); it!=cutsMap.end(); it++) {
|
for (auto it = cutsMap.begin(); it != cutsMap.end(); it++)
|
||||||
(static_cast<TNamed*>(it->second))->SetName(it->first.c_str());
|
{
|
||||||
|
(static_cast<TNamed *>(it->second))->SetName(it->first.c_str());
|
||||||
it->second->Write();
|
it->second->Write();
|
||||||
}
|
}
|
||||||
ofile->Close();
|
ofile->Close();
|
||||||
std::cout << "Wrote " << oMap.size() << " histograms to TFile " << std::string(ofile->GetName()) << std::endl;
|
std::cout << "Wrote " << oMap.size() << " histograms to TFile " << std::string(ofile->GetName()) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistPlotter::FillGraph(const std::string& name, float valuex, float valuey, float errx, float erry) {
|
void HistPlotter::FillGraph(const std::string &name, float valuex, float valuey, float errx, float erry)
|
||||||
|
{
|
||||||
/*! \fn void FillGraph()
|
/*! \fn void FillGraph()
|
||||||
\brief
|
\brief
|
||||||
- Creates a TGraphError in memory with name 'name' if it doesn't exist, and fills it with valuex, valuey
|
- Creates a TGraphError in memory with name 'name' if it doesn't exist, and fills it with valuex, valuey
|
||||||
|
|
@ -174,12 +209,14 @@ void HistPlotter::FillGraph(const std::string& name, float valuex, float valuey,
|
||||||
\return No return void
|
\return No return void
|
||||||
*/
|
*/
|
||||||
auto result = oMap.find(name);
|
auto result = oMap.find(name);
|
||||||
if(result==oMap.end()) {
|
if (result == oMap.end())
|
||||||
|
{
|
||||||
TGraphErrors *tempG = new TGraphErrors();
|
TGraphErrors *tempG = new TGraphErrors();
|
||||||
tempG->SetName(name.c_str());
|
tempG->SetName(name.c_str());
|
||||||
oMap.insert(std::make_pair(name,static_cast<TObject*>(tempG)));
|
oMap.insert(std::make_pair(name, static_cast<TObject *>(tempG)));
|
||||||
}
|
}
|
||||||
if(!oMap.at(name)->InheritsFrom("TGraphErrors")) {
|
if (!oMap.at(name)->InheritsFrom("TGraphErrors"))
|
||||||
|
{
|
||||||
std::cerr << "Object " << name << " refers to something other than a TGraph*, not filling it hence!" << std::endl;
|
std::cerr << "Object " << name << " refers to something other than a TGraph*, not filling it hence!" << std::endl;
|
||||||
std::cerr << "Abort.." << std::endl;
|
std::cerr << "Abort.." << std::endl;
|
||||||
FlushToDisk();
|
FlushToDisk();
|
||||||
|
|
@ -188,7 +225,8 @@ void HistPlotter::FillGraph(const std::string& name, float valuex, float valuey,
|
||||||
// static_cast<TGraphErrors*>(oMap.at(name))->AddPointError(valuex,valuey,errx,erry);
|
// static_cast<TGraphErrors*>(oMap.at(name))->AddPointError(valuex,valuey,errx,erry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistPlotter::Fill1D(const std::string& name, int nbinsx, float xlow, float xhigh, float value) {
|
void HistPlotter::Fill1D(const std::string &name, int nbinsx, float xlow, float xhigh, float value)
|
||||||
|
{
|
||||||
/*! \fn void Fill1D()
|
/*! \fn void Fill1D()
|
||||||
\brief
|
\brief
|
||||||
- Creates a TH1F in memory with name 'name' if it doesn't exist, and fills it with valuex, valuey
|
- Creates a TH1F in memory with name 'name' if it doesn't exist, and fills it with valuex, valuey
|
||||||
|
|
@ -201,28 +239,33 @@ void HistPlotter::Fill1D(const std::string& name, int nbinsx, float xlow, float
|
||||||
\param value The bin corresponding to value in (nbinsx, xlow, xhigh) is incremented by 1
|
\param value The bin corresponding to value in (nbinsx, xlow, xhigh) is incremented by 1
|
||||||
\return No return void
|
\return No return void
|
||||||
*/
|
*/
|
||||||
auto result = oMap.find(name); //result is an iterator
|
auto result = oMap.find(name); // result is an iterator
|
||||||
if(result==oMap.end()) {
|
if (result == oMap.end())
|
||||||
TH1F* temp1D = new TH1F(name.c_str(), name.c_str(), nbinsx, xlow, xhigh);
|
{
|
||||||
oMap.insert(std::make_pair(name,static_cast<TObject*>(temp1D)));
|
TH1F *temp1D = new TH1F(name.c_str(), name.c_str(), nbinsx, xlow, xhigh);
|
||||||
|
oMap.insert(std::make_pair(name, static_cast<TObject *>(temp1D)));
|
||||||
onedimcache.insert(std::make_pair(name, std::vector<double>()));
|
onedimcache.insert(std::make_pair(name, std::vector<double>()));
|
||||||
onedimcache[name].reserve(16384);
|
onedimcache[name].reserve(16384);
|
||||||
} else if(foldersForObjects.find(oMap.at(name))!=foldersForObjects.end()) { //shouldn't have a folder associated with it
|
}
|
||||||
std::cerr << "Object " << name << " already registered at " << foldersForObjects[oMap[name]] << ", choose a different name for the histogram to be stored in toplevel .." << std::endl;
|
else if (foldersForObjects.find(oMap.at(name)) != foldersForObjects.end())
|
||||||
|
{ // shouldn't have a folder associated with it
|
||||||
|
std::cerr << "Object " << name << " already registered at " << foldersForObjects[oMap[name]] << ", choose a different name for the histogram to be stored in toplevel .." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check if the string 'name' maps to a 1D hist. If there's any other object by this name raise issue
|
// Check if the string 'name' maps to a 1D hist. If there's any other object by this name raise issue
|
||||||
if(!oMap.at(name)->InheritsFrom("TH1F")) {
|
if (!oMap.at(name)->InheritsFrom("TH1F"))
|
||||||
|
{
|
||||||
std::cerr << "Object " << name << " refers to something other than a TH1*, not filling it hence!" << std::endl;
|
std::cerr << "Object " << name << " refers to something other than a TH1*, not filling it hence!" << std::endl;
|
||||||
std::cerr << "Abort.." << std::endl;
|
std::cerr << "Abort.." << std::endl;
|
||||||
FlushToDisk();
|
FlushToDisk();
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
onedimcache[name].emplace_back(value);
|
onedimcache[name].emplace_back(value);
|
||||||
//static_cast<TH1F*>(oMap.at(name))->Fill(value);
|
// static_cast<TH1F*>(oMap.at(name))->Fill(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistPlotter::Fill1D(const std::string& name, int nbinsx, float xlow, float xhigh, float value, const std::string& foldername) {
|
void HistPlotter::Fill1D(const std::string &name, int nbinsx, float xlow, float xhigh, float value, const std::string &foldername)
|
||||||
|
{
|
||||||
/*! \fn void Fill1D()
|
/*! \fn void Fill1D()
|
||||||
\brief
|
\brief
|
||||||
- Creates a TH1F in memory with name 'name' if it doesn't exist, and fills it with valuex, valuey
|
- Creates a TH1F in memory with name 'name' if it doesn't exist, and fills it with valuex, valuey
|
||||||
|
|
@ -238,39 +281,49 @@ void HistPlotter::Fill1D(const std::string& name, int nbinsx, float xlow, float
|
||||||
\return No return -- void
|
\return No return -- void
|
||||||
*/
|
*/
|
||||||
|
|
||||||
auto result = oMap.find(name); //result is an iterator
|
auto result = oMap.find(name); // result is an iterator
|
||||||
if(result==oMap.end()) {
|
if (result == oMap.end())
|
||||||
TH1F* temp1D = new TH1F(name.c_str(), name.c_str(), nbinsx, xlow, xhigh);
|
{
|
||||||
oMap.insert(std::make_pair(name,static_cast<TObject*>(temp1D)));
|
TH1F *temp1D = new TH1F(name.c_str(), name.c_str(), nbinsx, xlow, xhigh);
|
||||||
|
oMap.insert(std::make_pair(name, static_cast<TObject *>(temp1D)));
|
||||||
onedimcache.insert(std::make_pair(name, std::vector<double>()));
|
onedimcache.insert(std::make_pair(name, std::vector<double>()));
|
||||||
onedimcache[name].reserve(16384);
|
onedimcache[name].reserve(16384);
|
||||||
if(foldername!="") {
|
if (foldername != "")
|
||||||
if(folderList.find(foldername)==folderList.end()) {
|
{
|
||||||
|
if (folderList.find(foldername) == folderList.end())
|
||||||
|
{
|
||||||
folderList.insert(foldername);
|
folderList.insert(foldername);
|
||||||
}
|
}
|
||||||
foldersForObjects.insert(std::make_pair(static_cast<TObject*>(temp1D),foldername));
|
foldersForObjects.insert(std::make_pair(static_cast<TObject *>(temp1D), foldername));
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//object is present in map, but we enforce unique names
|
|
||||||
//it must already have a folder attached to it
|
|
||||||
if(foldersForObjects.find(oMap.at(name))==foldersForObjects.end()) {
|
|
||||||
std::cerr << "Object " << name << " already registered at toplevel, choose a different name for the histogram to be stored in " << foldername << " folder .." << std::endl;
|
|
||||||
} else if(foldersForObjects[oMap[name]]!=foldername) {
|
|
||||||
std::cerr << "Object " << name << " already registered at " << foldersForObjects[oMap[name]] << ", choose a different name for the histogram to be stored in " << foldername << " folder .." << std::endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Check if the string 'name' maps to a 1D hist. If there's any other object by this name raise issue
|
else
|
||||||
if(!oMap.at(name)->InheritsFrom("TH1F")) {
|
{
|
||||||
|
// object is present in map, but we enforce unique names
|
||||||
|
// it must already have a folder attached to it
|
||||||
|
if (foldersForObjects.find(oMap.at(name)) == foldersForObjects.end())
|
||||||
|
{
|
||||||
|
std::cerr << "Object " << name << " already registered at toplevel, choose a different name for the histogram to be stored in " << foldername << " folder .." << std::endl;
|
||||||
|
}
|
||||||
|
else if (foldersForObjects[oMap[name]] != foldername)
|
||||||
|
{
|
||||||
|
std::cerr << "Object " << name << " already registered at " << foldersForObjects[oMap[name]] << ", choose a different name for the histogram to be stored in " << foldername << " folder .." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check if the string 'name' maps to a 1D hist. If there's any other object by this name raise issue
|
||||||
|
if (!oMap.at(name)->InheritsFrom("TH1F"))
|
||||||
|
{
|
||||||
std::cerr << "Object " << name << " refers to something other than a TH1*, not filling it hence!" << std::endl;
|
std::cerr << "Object " << name << " refers to something other than a TH1*, not filling it hence!" << std::endl;
|
||||||
std::cerr << "Abort.." << std::endl;
|
std::cerr << "Abort.." << std::endl;
|
||||||
FlushToDisk();
|
FlushToDisk();
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
onedimcache[name].emplace_back(value);
|
onedimcache[name].emplace_back(value);
|
||||||
//static_cast<TH1F*>(oMap.at(name))->Fill(value);
|
// static_cast<TH1F*>(oMap.at(name))->Fill(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistPlotter::Fill2D(const std::string& name, int nbinsx, float xlow, float xhigh, int nbinsy, float ylow, float yhigh, float valuex, float valuey) {
|
void HistPlotter::Fill2D(const std::string &name, int nbinsx, float xlow, float xhigh, int nbinsy, float ylow, float yhigh, float valuex, float valuey)
|
||||||
|
{
|
||||||
/*! \fn void Fill2D()
|
/*! \fn void Fill2D()
|
||||||
\brief
|
\brief
|
||||||
- Creates a TH2F in memory with name 'name' if it doesn't exist, and fills it with valuex, valuey
|
- Creates a TH2F in memory with name 'name' if it doesn't exist, and fills it with valuex, valuey
|
||||||
|
|
@ -287,19 +340,23 @@ void HistPlotter::Fill2D(const std::string& name, int nbinsx, float xlow, float
|
||||||
\return No return -- void
|
\return No return -- void
|
||||||
*/
|
*/
|
||||||
|
|
||||||
auto result = oMap.find(name); //result is an iterator
|
auto result = oMap.find(name); // result is an iterator
|
||||||
if(result==oMap.end()) {
|
if (result == oMap.end())
|
||||||
TH2F* temp2D = new TH2F(name.c_str(), name.c_str(), nbinsx, xlow, xhigh, nbinsy, ylow, yhigh);
|
{
|
||||||
oMap.insert(std::make_pair(name,static_cast<TObject*>(temp2D)));
|
TH2F *temp2D = new TH2F(name.c_str(), name.c_str(), nbinsx, xlow, xhigh, nbinsy, ylow, yhigh);
|
||||||
twodimcache.insert(std::make_pair(name, std::make_pair(std::vector<double>(),std::vector<double>())));
|
oMap.insert(std::make_pair(name, static_cast<TObject *>(temp2D)));
|
||||||
|
twodimcache.insert(std::make_pair(name, std::make_pair(std::vector<double>(), std::vector<double>())));
|
||||||
twodimcache[name].first.reserve(16384);
|
twodimcache[name].first.reserve(16384);
|
||||||
twodimcache[name].second.reserve(16384);
|
twodimcache[name].second.reserve(16384);
|
||||||
} else if(foldersForObjects.find(oMap.at(name))!=foldersForObjects.end()) { //shouldn't have a folder associated with it
|
}
|
||||||
std::cerr << "Object " << name << " already registered at " << foldersForObjects[oMap[name]] << ", choose a different name for the histogram to be stored in toplevel .." << std::endl;
|
else if (foldersForObjects.find(oMap.at(name)) != foldersForObjects.end())
|
||||||
|
{ // shouldn't have a folder associated with it
|
||||||
|
std::cerr << "Object " << name << " already registered at " << foldersForObjects[oMap[name]] << ", choose a different name for the histogram to be stored in toplevel .." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check if the string 'name' maps to a 1D hist. If there's any other object by this name raise issue
|
// Check if the string 'name' maps to a 1D hist. If there's any other object by this name raise issue
|
||||||
if(!oMap.at(name)->InheritsFrom("TH2F")) {
|
if (!oMap.at(name)->InheritsFrom("TH2F"))
|
||||||
|
{
|
||||||
std::cerr << "Object " << name << " refers to something other than a TH2*, not filling it hence!" << std::endl;
|
std::cerr << "Object " << name << " refers to something other than a TH2*, not filling it hence!" << std::endl;
|
||||||
std::cerr << "Abort.." << std::endl;
|
std::cerr << "Abort.." << std::endl;
|
||||||
FlushToDisk();
|
FlushToDisk();
|
||||||
|
|
@ -307,10 +364,11 @@ void HistPlotter::Fill2D(const std::string& name, int nbinsx, float xlow, float
|
||||||
}
|
}
|
||||||
twodimcache[name].first.emplace_back(valuex);
|
twodimcache[name].first.emplace_back(valuex);
|
||||||
twodimcache[name].second.emplace_back(valuey);
|
twodimcache[name].second.emplace_back(valuey);
|
||||||
//static_cast<TH2F*>(oMap.at(name))->Fill(valuex,valuey);
|
// static_cast<TH2F*>(oMap.at(name))->Fill(valuex,valuey);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistPlotter::Fill2D(const std::string& name, int nbinsx, float xlow, float xhigh, int nbinsy, float ylow, float yhigh, float valuex, float valuey, const std::string& foldername) {
|
void HistPlotter::Fill2D(const std::string &name, int nbinsx, float xlow, float xhigh, int nbinsy, float ylow, float yhigh, float valuex, float valuey, const std::string &foldername)
|
||||||
|
{
|
||||||
/*! \fn void Fill2D()
|
/*! \fn void Fill2D()
|
||||||
\brief
|
\brief
|
||||||
- Creates a TH2F in memory with name 'name' if it doesn't exist, and fills it with valuex, valuey
|
- Creates a TH2F in memory with name 'name' if it doesn't exist, and fills it with valuex, valuey
|
||||||
|
|
@ -330,31 +388,40 @@ void HistPlotter::Fill2D(const std::string& name, int nbinsx, float xlow, float
|
||||||
\return No return -- void
|
\return No return -- void
|
||||||
*/
|
*/
|
||||||
|
|
||||||
auto result = oMap.find(name); //result is an iterator
|
auto result = oMap.find(name); // result is an iterator
|
||||||
if(result==oMap.end()) {
|
if (result == oMap.end())
|
||||||
TH2F* temp2D = new TH2F(name.c_str(), name.c_str(), nbinsx, xlow, xhigh, nbinsy, ylow, yhigh);
|
{
|
||||||
oMap.insert(std::make_pair(name,static_cast<TObject*>(temp2D)));
|
TH2F *temp2D = new TH2F(name.c_str(), name.c_str(), nbinsx, xlow, xhigh, nbinsy, ylow, yhigh);
|
||||||
twodimcache.insert(std::make_pair(name, std::make_pair(std::vector<double>(),std::vector<double>())));
|
oMap.insert(std::make_pair(name, static_cast<TObject *>(temp2D)));
|
||||||
|
twodimcache.insert(std::make_pair(name, std::make_pair(std::vector<double>(), std::vector<double>())));
|
||||||
twodimcache[name].first.reserve(16384);
|
twodimcache[name].first.reserve(16384);
|
||||||
twodimcache[name].second.reserve(16384);
|
twodimcache[name].second.reserve(16384);
|
||||||
if(foldername!="") {
|
if (foldername != "")
|
||||||
if(folderList.find(foldername)==folderList.end()) {
|
{
|
||||||
|
if (folderList.find(foldername) == folderList.end())
|
||||||
|
{
|
||||||
folderList.insert(foldername);
|
folderList.insert(foldername);
|
||||||
}
|
}
|
||||||
foldersForObjects.insert(std::make_pair(static_cast<TObject*>(temp2D),foldername));
|
foldersForObjects.insert(std::make_pair(static_cast<TObject *>(temp2D), foldername));
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
//object is present in map, but we enforce unique names
|
else
|
||||||
//it must already have a folder attached to it
|
{
|
||||||
if(foldersForObjects.find(oMap.at(name))==foldersForObjects.end()) {
|
// object is present in map, but we enforce unique names
|
||||||
|
// it must already have a folder attached to it
|
||||||
|
if (foldersForObjects.find(oMap.at(name)) == foldersForObjects.end())
|
||||||
|
{
|
||||||
std::cerr << "Object " << name << " already registered at toplevel, choose a different name for the histogram to be stored in " << foldername << " folder .." << std::endl;
|
std::cerr << "Object " << name << " already registered at toplevel, choose a different name for the histogram to be stored in " << foldername << " folder .." << std::endl;
|
||||||
} else if(foldersForObjects[oMap.at(name)]!=foldername) {
|
}
|
||||||
std::cerr << "Object " << name << " already registered at " << foldersForObjects[oMap[name]] << ", choose a different name for the histogram to be stored in " << foldername << " folder .." << std::endl;
|
else if (foldersForObjects[oMap.at(name)] != foldername)
|
||||||
|
{
|
||||||
|
std::cerr << "Object " << name << " already registered at " << foldersForObjects[oMap[name]] << ", choose a different name for the histogram to be stored in " << foldername << " folder .." << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check if the string 'name' maps to a 1D hist. If there's any other object by this name raise issue
|
// Check if the string 'name' maps to a 1D hist. If there's any other object by this name raise issue
|
||||||
if(!oMap.at(name)->InheritsFrom("TH2F")) {
|
if (!oMap.at(name)->InheritsFrom("TH2F"))
|
||||||
|
{
|
||||||
std::cerr << "Object " << name << " refers to something other than a TH2*, not filling it hence!" << std::endl;
|
std::cerr << "Object " << name << " refers to something other than a TH2*, not filling it hence!" << std::endl;
|
||||||
std::cerr << "Abort.." << std::endl;
|
std::cerr << "Abort.." << std::endl;
|
||||||
FlushToDisk();
|
FlushToDisk();
|
||||||
|
|
@ -362,10 +429,11 @@ void HistPlotter::Fill2D(const std::string& name, int nbinsx, float xlow, float
|
||||||
}
|
}
|
||||||
twodimcache[name].first.emplace_back(valuex);
|
twodimcache[name].first.emplace_back(valuex);
|
||||||
twodimcache[name].second.emplace_back(valuey);
|
twodimcache[name].second.emplace_back(valuey);
|
||||||
//static_cast<TH2F*>(oMap.at(name))->Fill(valuex,valuey);
|
// static_cast<TH2F*>(oMap.at(name))->Fill(valuex,valuey);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistPlotter::ReadCuts(std::string filename) {
|
void HistPlotter::ReadCuts(std::string filename)
|
||||||
|
{
|
||||||
/*! \fn void ReadCuts()
|
/*! \fn void ReadCuts()
|
||||||
\brief Reads a list of cuts from a file. The file must have the format below, two columns
|
\brief Reads a list of cuts from a file. The file must have the format below, two columns
|
||||||
- Column#1 - path to a file that contains a single TCutG object named "CUTG", the default name in ROOT.
|
- Column#1 - path to a file that contains a single TCutG object named "CUTG", the default name in ROOT.
|
||||||
|
|
@ -377,27 +445,31 @@ void HistPlotter::ReadCuts(std::string filename) {
|
||||||
std::ifstream infile;
|
std::ifstream infile;
|
||||||
infile.open(filename);
|
infile.open(filename);
|
||||||
std::string cutfilename, cutname;
|
std::string cutfilename, cutname;
|
||||||
for(std::string line; std::getline(infile, line); ) {
|
for (std::string line; std::getline(infile, line);)
|
||||||
if(line.size()!=0 && line[0]=='#')
|
{
|
||||||
; //don't do anything with '#' lines
|
if (line.size() != 0 && line[0] == '#')
|
||||||
else {
|
; // don't do anything with '#' lines
|
||||||
|
else
|
||||||
|
{
|
||||||
std::stringstream ss(line);
|
std::stringstream ss(line);
|
||||||
ss>>cutfilename>>cutname;
|
ss >> cutfilename >> cutname;
|
||||||
|
|
||||||
TFile f(cutfilename.c_str());
|
TFile f(cutfilename.c_str());
|
||||||
if(f.IsZombie()) {
|
if (f.IsZombie())
|
||||||
|
{
|
||||||
std::cerr << "Cannot open cutfile " << cutfilename << " .. skipping.." << std::endl;
|
std::cerr << "Cannot open cutfile " << cutfilename << " .. skipping.." << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
TCutG *cut = (TCutG*)(f.Get("CUTG"));
|
TCutG *cut = (TCutG *)(f.Get("CUTG"));
|
||||||
cutsMap.insert(std::make_pair(cutname,static_cast<TObject*>(cut)));
|
cutsMap.insert(std::make_pair(cutname, static_cast<TObject *>(cut)));
|
||||||
f.Close();
|
f.Close();
|
||||||
} //else
|
} // else
|
||||||
}//for loop
|
} // for loop
|
||||||
infile.close();
|
infile.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistPlotter::PrintObjects() {
|
void HistPlotter::PrintObjects()
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
void PrintObjects()
|
void PrintObjects()
|
||||||
Prints the contents of the unordered_maps oMap and cutsMap to facilitate debugging
|
Prints the contents of the unordered_maps oMap and cutsMap to facilitate debugging
|
||||||
|
|
@ -405,11 +477,13 @@ void HistPlotter::PrintObjects() {
|
||||||
*/
|
*/
|
||||||
std::cout << "Type | Name " << std::endl;
|
std::cout << "Type | Name " << std::endl;
|
||||||
std::cout << "---- | --------------------- " << std::endl;
|
std::cout << "---- | --------------------- " << std::endl;
|
||||||
for(auto it=oMap.begin(); it!=oMap.end(); it++ ) {
|
for (auto it = oMap.begin(); it != oMap.end(); it++)
|
||||||
std::cout << it->second->ClassName() << " | "<< it->first << std::endl;
|
{
|
||||||
|
std::cout << it->second->ClassName() << " | " << it->first << std::endl;
|
||||||
}
|
}
|
||||||
for(auto it=cutsMap.begin(); it!=cutsMap.end(); it++ ) {
|
for (auto it = cutsMap.begin(); it != cutsMap.end(); it++)
|
||||||
std::cout << it->second->ClassName() << " | "<< it->first << std::endl;
|
{
|
||||||
|
std::cout << it->second->ClassName() << " | " << it->first << std::endl;
|
||||||
}
|
}
|
||||||
std::cout << "---- | --------------------- " << std::endl;
|
std::cout << "---- | --------------------- " << std::endl;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
44
TrackRecon.C
44
TrackRecon.C
|
|
@ -56,7 +56,9 @@ bool process_alpha_proton_scattering = false,
|
||||||
|
|
||||||
// --- Geometry, Calibration, & Model Variables ---
|
// --- Geometry, Calibration, & Model Variables ---
|
||||||
double source_vertex = 53.0,
|
double source_vertex = 53.0,
|
||||||
z_entrance = -174.3 - 9.7 - 100.0,
|
// z_entrance = -174.3 - 9.7 - 100.0,
|
||||||
|
z_entrance = -174.3 - 9.7 - 270.0, // new measurement of the chamber length puts the chamber at
|
||||||
|
// 1175mm instead of 1105, plus some part of the window actually lies outside the chamber
|
||||||
dither_sigma = 8.0,
|
dither_sigma = 8.0,
|
||||||
dither_sigma_c0 = 16.0,
|
dither_sigma_c0 = 16.0,
|
||||||
cathode_gain = 1.0,
|
cathode_gain = 1.0,
|
||||||
|
|
@ -511,6 +513,8 @@ void TrackRecon::Begin(TTree * /*tree*/)
|
||||||
else
|
else
|
||||||
plotter = new HistPlotter("Analyzer_SX3.root", "TFILE");
|
plotter = new HistPlotter("Analyzer_SX3.root", "TFILE");
|
||||||
|
|
||||||
|
plotter->set_barrier_limit(getenv("FLUSH_BARRIER") ? std::atoll(getenv("FLUSH_BARRIER")) : 50000);
|
||||||
|
|
||||||
if (getenv("reactiondata"))
|
if (getenv("reactiondata"))
|
||||||
{
|
{
|
||||||
reactiondata = std::atoi(getenv("reactiondata"));
|
reactiondata = std::atoi(getenv("reactiondata"));
|
||||||
|
|
@ -1008,8 +1012,46 @@ inline void pcEnergyCalibrationAccumulateProton(const std::vector<Event> &PC_Eve
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reads VmRSS (resident memory, MB) for this process from /proc/self/status.
|
||||||
|
// Returns -1.0 if unavailable (e.g. non-Linux) so callers can skip the check.
|
||||||
|
inline double currentRSS_MB()
|
||||||
|
{
|
||||||
|
std::ifstream statusFile("/proc/self/status");
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(statusFile, line))
|
||||||
|
{
|
||||||
|
if (line.compare(0, 6, "VmRSS:") == 0)
|
||||||
|
{
|
||||||
|
std::istringstream iss(line.substr(6));
|
||||||
|
double kb = -1.0;
|
||||||
|
iss >> kb;
|
||||||
|
return kb > 0.0 ? kb / 1024.0 : -1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
Bool_t TrackRecon::Process(Long64_t entry)
|
Bool_t TrackRecon::Process(Long64_t entry)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
static const double maxRSS_MB = getenv("MAX_RSS_MB") ? std::atof(getenv("MAX_RSS_MB")) : 0.0;
|
||||||
|
static const Long64_t checkStride = getenv("MEMCHECK_STRIDE") ? std::atoll(getenv("MEMCHECK_STRIDE")) : 5000;
|
||||||
|
static Long64_t processedCount = 0;
|
||||||
|
++processedCount;
|
||||||
|
|
||||||
|
if (maxRSS_MB > 0.0 && (processedCount % checkStride == 0))
|
||||||
|
{
|
||||||
|
double rss = currentRSS_MB();
|
||||||
|
if (rss > 0.0 && rss > maxRSS_MB)
|
||||||
|
{
|
||||||
|
std::cout << "MAX_RSS_MB (" << maxRSS_MB << ") exceeded (RSS=" << rss
|
||||||
|
<< " MB) at entry " << entry << " -- forcing a cache flush and continuing." << std::endl;
|
||||||
|
plotter->force_flush_caches();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plotter->barrier_increment();
|
||||||
|
|
||||||
hitPos.Clear();
|
hitPos.Clear();
|
||||||
qqqenergy = -1;
|
qqqenergy = -1;
|
||||||
qqqtimestamp = -1;
|
qqqtimestamp = -1;
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ process_run() {
|
||||||
export -f process_run
|
export -f process_run
|
||||||
|
|
||||||
echo "Starting parallel processing..."
|
echo "Starting parallel processing..."
|
||||||
time parallel --bar -j 6 process_run ::: {24..41}
|
# time parallel --bar -j 6 process_run ::: {24..41}
|
||||||
time parallel --bar -j 8 process_run ::: {50..59}
|
time parallel --bar -j 8 process_run ::: {50..59}
|
||||||
# time parallel --bar -j 4 process_run ::: 62 63 66 67 68
|
# time parallel --bar -j 4 process_run ::: 62 63 66 67 68
|
||||||
# time parallel --bar -j 1 process_run ::: 73
|
# time parallel --bar -j 1 process_run ::: 73
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user