ATLAS Offline Software
Loading...
Searching...
No Matches
postProcessIDPVMHistos.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 postProcessIDPVMHistos.cxx:

Go to the source code of this file.

Functions

bool file_exists (const string &p_name)
bool isResolutionHelper (TObject *entry)
std::vector< std::string > getObservableAndResoAndSuffix (const TObject *resHelper)
std::string getResoType (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)
int postProcessDir (TDirectory *dir, IDPVM::ResolutionHelper &theHelper)
int pproc_file (const std::string &p_infile)
int main (int argc, char *argv[])

Detailed Description


Author
: Max Goblirsch Based on code by Liza Mijovic, Soeren Prell

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


Definition in file postProcessIDPVMHistos.cxx.

Function Documentation

◆ cloneExisting()

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

Definition at line 72 of file postProcessIDPVMHistos.cxx.

72 {
73 auto *h = gDirectory->Get(name.c_str());
74 if (!h){
75 std::cerr << "Could not find existing histogram "<<name<<" - will not postprocess "<<std::endl;
76 return nullptr;
77 }
78 auto *ret = dynamic_cast<TH1*>(h->Clone(name.c_str()));
79 if (!ret){
80 std::cerr << "Found an existing object "<<name<<", but it is not a histogram ("<<h->IsA()->GetName()<<") - will not postprocess "<<std::endl;
81 }
82 return ret; // will also catch ret == nullptr
83}
Header file for AthHistogramAlgorithm.

◆ file_exists()

bool file_exists ( const string & p_name)

Definition at line 31 of file postProcessIDPVMHistos.cxx.

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

◆ getObservableAndResoAndSuffix()

std::vector< std::string > getObservableAndResoAndSuffix ( const TObject * resHelper)

Definition at line 43 of file postProcessIDPVMHistos.cxx.

43 {
44 const std::string name{resHelper->GetName()};
45 const std::string keyWord {"Helper_"};
46 const size_t offset = keyWord.size();
47 auto start = name.find(keyWord)+offset;
48 auto sep = name.find('_',start);
49 auto sep2 = name.find('_',sep+1);
50
51 std::string first = name.substr(start, sep - start);
52 std::string second;
53 std::string third;
54 if (sep2 == std::string::npos) {
55 // Only one underscore after Helper_
56 second = name.substr(sep + 1);
57 } else {
58 second = name.substr(sep + 1, sep2 - sep - 1);
59 third = name.substr(sep2 + 1);
60 }
61 // coverity[copy_constructor_call]
62 return {first, second, third};
63}
bool first
Definition DeMoScan.py:534

◆ getPullAndResoNames()

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

Definition at line 86 of file postProcessIDPVMHistos.cxx.

86 {
87 if (type == "res"){
88 return {"resolution","resmean"};
89 }
90 else if (type == "pull"){
91 return {"pullwidth","pullmean"};
92 }
93 else {
94 std::cerr << " Not able to identify the histogram names for a resolution type "<<type<<" - supported are 'res' and 'pull'. "<<std::endl;
95 }
96 return {"",""};
97}

◆ getResoType()

std::string getResoType ( const TObject * resHelper)

Definition at line 66 of file postProcessIDPVMHistos.cxx.

66 {
67 std::string aux{resHelper->GetName()};
68 return aux.substr(0, aux.find("Helper"));
69}

◆ isResolutionHelper()

bool isResolutionHelper ( TObject * entry)

Definition at line 36 of file postProcessIDPVMHistos.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.

hadd imitation. Ugly, but allows this to run in PhysVal merge transforms. We deliberately ignore the first arg ("-f") in the following. This is because the physval merge step requires passing a "-f" ...

copy the input file to the output file

and mark the output for postprocessing. Input stays invariant in this mode

check if the input exists

and post-process if it does

Definition at line 166 of file postProcessIDPVMHistos.cxx.

166 {
167
168 std::string infile{""};
170 if (argc == 2){
171 infile = argv[1];
172 }
177 else if (argc == 4 && std::string(argv[1]) == std::string{"-f"}){
179 gSystem->CopyFile(argv[3],argv[2],true);
181 infile = argv[2];
182 }
183 else {
184 std::cerr<<" Usage: postProcessIDPVMHistos <File to post-process>"<<std::endl;
185 std::cerr<< " where the file is typically obtained by hadding" << std::endl;
186 std::cerr<< " outputs of several independent IDPVM runs." << std::endl;
187 std::cerr<<" Alternative usage: postProcessIDPVMHistos -f <desired output file name> <File to post-process>"<<std::endl;
188 std::cerr<< " imitates a hadd-like signature for PhysVal merging." << std::endl;
189 return 1;
190 }
192 if (!file_exists(infile)) {
193 std::cerr << "Error: invalid input file: " << infile << std::endl;
194 return 1;
195 }
197 std::cout << " Post-processing file " << infile << "\n" << std::endl;
198 return pproc_file(infile);
199}
str infile
Definition run.py:13
int pproc_file(const std::string &p_infile)
bool file_exists(const string &p_name)

◆ postProcessDir()

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

Definition at line 125 of file postProcessIDPVMHistos.cxx.

125 {
126
127 int outcome = 0;
128 auto theCWD = gDirectory;
129 // walk through all keys in this directory
130 dir->cd();
131 auto *keys = dir->GetListOfKeys();
132 for (auto *const key : *keys){
133 // Check if it's a directory and handle separately
134 TDirectory* theDir = dynamic_cast<TDirectory*>(dir->Get(key->GetName()));
135 if (theDir){
136 outcome |= postProcessDir(theDir, theHelper);
137 continue; // Do NOT delete directories, ROOT manages them
138 }
139
140 // If it's a histogram, wrap it in a unique_ptr
141 std::unique_ptr<TObject> gotIt(dir->Get(key->GetName()));
142 if (isResolutionHelper(gotIt.get())){
143 outcome |= postProcessHistos(gotIt.get(), theHelper);
144 }
145 }
146 theCWD->cd();
147 return outcome;
148}
int postProcessDir(TDirectory *dir, IDPVM::ResolutionHelper &theHelper)
bool isResolutionHelper(TObject *entry)
int postProcessHistos(TObject *resHelper, IDPVM::ResolutionHelper &theHelper)

◆ postProcessHistos()

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

Definition at line 99 of file postProcessIDPVMHistos.cxx.

99 {
100 // here we have to rely on the naming conventions of IDPVM to identify what we are looking at
101 auto vars = getObservableAndResoAndSuffix(resHelper);
102 auto type = getResoType(resHelper);
103 // cast to TH2
104 TH2* resHelper2D = dynamic_cast<TH2*>(resHelper);
105 if (!resHelper2D){
106 std::cerr <<"Unable to reduce the histogram "<<resHelper->GetName()<<" to a TH2 - this histo can not yet be postprocessed! " <<std::endl;
107 return 1;
108 }
109 const auto & oneDimNames = getPullAndResoNames(type);
110 // get the corresponding 1D histos by cloning the existing ones in the same folder
111 std::string suffix = "_vs_"+vars[0]+"_"+vars[1];
112 if(!vars[2].empty()) suffix += "_" + vars[2];
113 TH1* h_width = cloneExisting(oneDimNames.first+suffix);
114 TH1* h_mean = cloneExisting(oneDimNames.second+suffix);
115 // then call the resolution helper as done in "online" IDPVM
116 theHelper.makeResolutions(resHelper2D, h_width, h_mean);
117 // update our 1D histos
118 h_width->Write();
119 h_mean->Write();
120 // and we are done
121 return 0;
122}
static const Attributes_t empty
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::string getResoType(const TObject *resHelper)
TH1 * cloneExisting(const std::string &name)
std::vector< std::string > getObservableAndResoAndSuffix(const TObject *resHelper)
std::pair< std::string, std::string > getPullAndResoNames(const std::string &type)

◆ pproc_file()

int pproc_file ( const std::string & p_infile)

Definition at line 151 of file postProcessIDPVMHistos.cxx.

151 {
152
153 IDPVM::ResolutionHelper theHelper;
154
155 std::unique_ptr<TFile> infile(TFile::Open(p_infile.c_str(),"UPDATE"));
156 if (!infile || infile->IsZombie()) {
157 std::cerr << "could not open input file "<<p_infile<<" for updating "<< std::endl;
158 return 1;
159 }
160
161 int res = postProcessDir(infile.get(), theHelper); // recursively post-process the directory tree, starting from the root.
162 return res;
163}
std::pair< std::vector< unsigned int >, bool > res