ATLAS Offline Software
Loading...
Searching...
No Matches
postProcessIDTPMHistos.cxx File Reference
#include "InDetPhysValMonitoring/ResolutionHelper.h"
#include "TFile.h"
#include "TSystem.h"
#include "TH1.h"
#include "TH2.h"
#include "TObject.h"
#include <iostream>
#include <memory>
#include <string>
Include dependency graph for postProcessIDTPMHistos.cxx:

Go to the source code of this file.

Functions

bool file_exists (const string &p_name)
bool isResolutionHelper (TObject *entry)
std::pair< std::string, std::string > getTypeAndVars (const TObject *resHelper)
TH1 * cloneExisting (const std::string &name)
std::pair< std::string, std::string > getPullAndResoNames (const std::string &type)
int postProcessHistos (TObject *resHelper, IDPVM::ResolutionHelper &theHelper, IDPVM::ResolutionHelper::methods &theMethod)
int postProcessDir (TDirectory *dir, IDPVM::ResolutionHelper &theHelper, IDPVM::ResolutionHelper::methods &theMethod)
int pproc_file (const std::string &p_infile, const std::string &methodStr)
int main (int argc, char *argv[])

Detailed Description


Author
: Max Goblirsch Based on code by Liza Mijovic, Soeren Prell and the analogous script in IDPVM

Goal: Update resolutions extracted from 2D histograms after merging several output files (typically after grid running)


Definition in file postProcessIDTPMHistos.cxx.

Function Documentation

◆ cloneExisting()

TH1 * cloneExisting ( const std::string & name)

Definition at line 53 of file postProcessIDTPMHistos.cxx.

53 {
54 auto *h = gDirectory->Get(name.c_str());
55 if (!h){
56 std::cerr << "Could not find existing histogram "<<name<<" - will not postprocess "<<std::endl;
57 return nullptr;
58 }
59 auto *ret = dynamic_cast<TH1*>(h->Clone(name.c_str()));
60 if (!ret){
61 std::cerr << "Found an existing object "<<name<<", but it is not a histogram ("<<h->IsA()->GetName()<<") - will not postprocess "<<std::endl;
62 }
63 return ret; // will also catch ret == nullptr
64}
Header file for AthHistogramAlgorithm.

◆ file_exists()

bool file_exists ( const string & p_name)

Definition at line 31 of file postProcessIDTPMHistos.cxx.

31 {
32 return !gSystem->AccessPathName(p_name.c_str(), kFileExists);
33}

◆ getPullAndResoNames()

std::pair< std::string, std::string > getPullAndResoNames ( const std::string & type)

Definition at line 67 of file postProcessIDTPMHistos.cxx.

67 {
68 if (type == "res"){
69 return {"resolution","resmean"};
70 }
71 else if (type == "pull"){
72 return {"pullwidth","pullmean"};
73 }
74 else {
75 std::cerr << " Not able to identify the histogram names for a resolution type "<<type<<" - supported are 'res' and 'pull'. "<<std::endl;
76 }
77 return {"",""};
78}

◆ getTypeAndVars()

std::pair< std::string, std::string > getTypeAndVars ( const TObject * resHelper)

Definition at line 44 of file postProcessIDTPMHistos.cxx.

44 {
45 const std::string name{ resHelper->GetName() };
46 const std::string keyWord{ "Helper" };
47 const size_t pos = name.find( keyWord );
48 const size_t pos2 = pos + keyWord.size();
49 return { name.substr( 0, pos ), name.substr( pos2 ) };
50}

◆ isResolutionHelper()

bool isResolutionHelper ( TObject * entry)

Definition at line 36 of file postProcessIDTPMHistos.cxx.

36 {
37 const std::string objName{entry->GetName()};
38 return ((objName.find("resHelper") == 0 || objName.find("pullHelper") == 0) && dynamic_cast<TH1*>(entry));
39}

◆ main()

int main ( int argc,
char * argv[] )

Standard usage. The user passes a file they wish to update.

check if the input exists

and post-process if it does

Definition at line 174 of file postProcessIDTPMHistos.cxx.

174 {
175
176 std::string infile{""};
177 std::string methodStr{"iterRMS"};
179 if( argc >= 2 ) {
180 infile = argv[1];
181 if( argc == 3 ) methodStr = argv[2];
182 }
183 else {
184 std::cerr<<" Usage: postProcessIDTPMHistos <File to post-process> <resolution method>"<<std::endl;
185 std::cerr<< " where the file is typically obtained by hadding" << std::endl;
186 std::cerr<< " outputs of several independent IDTPM runs." << std::endl;
187 std::cerr<< " The resolution method (optional) is set by default to iterRMS_convergence." << std::endl;
188 return 1;
189 }
191 if (!file_exists(infile)) {
192 std::cerr << "Error: invalid input file: " << infile << std::endl;
193 return 1;
194 }
196 std::cout << " Post-processing file " << infile << "\n" << std::endl;
197 return pproc_file( infile, methodStr );
198}
str infile
Definition run.py:13
int pproc_file(const std::string &p_infile, const std::string &methodStr)
bool file_exists(const string &p_name)

◆ postProcessDir()

int postProcessDir ( TDirectory * dir,
IDPVM::ResolutionHelper & theHelper,
IDPVM::ResolutionHelper::methods & theMethod )

Definition at line 109 of file postProcessIDTPMHistos.cxx.

113{
114 int outcome = 0;
115 auto theCWD = gDirectory;
116 // walk through all keys in this directory
117 dir->cd();
118 auto *keys = dir->GetListOfKeys();
119 for (auto *const key : *keys){
120 // Check if it's a directory and handle separately
121 TDirectory* theDir = dynamic_cast<TDirectory*>(dir->Get(key->GetName()));
122 if (theDir){
123 outcome |= postProcessDir( theDir, theHelper, theMethod );
124 continue; // Do NOT delete directories, ROOT manages them
125 }
126
127 // If it's a histogram, wrap it in a unique_ptr
128 std::unique_ptr<TObject> gotIt(dir->Get(key->GetName()));
129 if (isResolutionHelper(gotIt.get())){
130 outcome |= postProcessHistos( gotIt.get(), theHelper, theMethod );
131 }
132 }
133 theCWD->Purge(); // deleting old cycles
134 theCWD->cd();
135 return outcome;
136}
int postProcessHistos(TObject *resHelper, IDPVM::ResolutionHelper &theHelper, IDPVM::ResolutionHelper::methods &theMethod)
bool isResolutionHelper(TObject *entry)
int postProcessDir(TDirectory *dir, IDPVM::ResolutionHelper &theHelper, IDPVM::ResolutionHelper::methods &theMethod)

◆ postProcessHistos()

int postProcessHistos ( TObject * resHelper,
IDPVM::ResolutionHelper & theHelper,
IDPVM::ResolutionHelper::methods & theMethod )

Definition at line 80 of file postProcessIDTPMHistos.cxx.

84{
85 // here we have to rely on the naming conventions of IDTPM to identify what we are looking at
86 std::string type = getTypeAndVars( resHelper ).first;
87 std::string vars = getTypeAndVars( resHelper ).second;
88
89 // cast to TH2
90 TH2* resHelper2D = dynamic_cast<TH2*>(resHelper);
91 if (!resHelper2D){
92 std::cerr <<"Unable to reduce the histogram "<<resHelper->GetName()<<" to a TH2 - this histo can not yet be postprocessed! " <<std::endl;
93 return 1;
94 }
95 const auto & oneDimNames = getPullAndResoNames(type);
96 // get the corresponding 1D histos by cloning the existing ones in the same folder
97 TH1* h_width = cloneExisting( oneDimNames.first + vars );
98 TH1* h_mean = cloneExisting( oneDimNames.second + vars );
99 // then call the resolution helper as done in "online" IDTPM
100 theHelper.makeResolutions( resHelper2D, h_width, h_mean, theMethod );
101 // update our 1D histos
102 h_width->Write();
103 h_mean->Write();
104 // and we are done
105 return 0;
106}
void makeResolutions(const TH2 *h_input2D, TH1 *hwidth, TH1 *hmean, TH1 *hproj[], bool saveProjections, IDPVM::ResolutionHelper::methods theMethod=IDPVM::ResolutionHelper::iterRMS_convergence)
extract 1D resolution plots from a 2D "residual vs observable" histogram.
std::pair< std::string, std::string > getTypeAndVars(const TObject *resHelper)
TH1 * cloneExisting(const std::string &name)
std::pair< std::string, std::string > getPullAndResoNames(const std::string &type)

◆ pproc_file()

int pproc_file ( const std::string & p_infile,
const std::string & methodStr )

Defining map for resolution method

Definition at line 139 of file postProcessIDTPMHistos.cxx.

139 {
140
141 IDPVM::ResolutionHelper theHelper;
143
144 std::unique_ptr<TFile> infile(TFile::Open(p_infile.c_str(),"UPDATE"));
145 if (!infile || infile->IsZombie()) {
146 std::cerr << "could not open input file "<<p_infile<<" for updating "<< std::endl;
147 return 1;
148 }
149
151 using methodMap_t = std::unordered_map<
153 methodMap_t methodMap = {
155 { "gaussFit" , IDPVM::ResolutionHelper::Gauss_fit },
158 };
159
160 methodMap_t::const_iterator mitr = methodMap.find( methodStr );
161 if( mitr == methodMap.end() ) {
162 std::cerr << "Error: Method " << methodStr <<
163 " not found. Using iterRMS by default." << std::endl;
165 } else {
166 theMethod = mitr->second;
167 }
168
169 int res = postProcessDir( infile.get(), theHelper, theMethod ); // recursively post-process the directory tree, starting from the root.
170 return res;
171}
std::pair< std::vector< unsigned int >, bool > res