forked from cms-analysis/HiggsAnalysis-HiggsToTauTau
-
Notifications
You must be signed in to change notification settings - Fork 0
/
decoupleShapes.C
161 lines (149 loc) · 5.95 KB
/
decoupleShapes.C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include <string>
#include <vector>
#include <iostream>
#include <regex.h>
#include <sys/types.h>
#include <TKey.h>
#include <TH1F.h>
#include <TFile.h>
#include <TROOT.h>
#include <TString.h>
#include <TLegend.h>
#include <TPaveText.h>
#include <TCollection.h>
/**
\class rescalSignal rescaleSignal.C "HiggsAnalysis/HiggsToTauTau/macros/rescaleSignal.C"
\brief macro to rescale the signal component(s) for histogram based limit inputs for limi calculation to an arbitary value.
Macro to rescale all signal components in a given input file for limit calculations
The macro searches the head of the file and the next level of histogram directories
from the head of the file on. All directories in the given layer will be searched for
histograms. All histograms that fullfill a given PATTERN will be scaled by a factor
SCALE. If the PATTERN is empty all histograms that start with 'Higgs', 'GGH', 'BBH',
'SM', 'VH', 'VBF' will be scaled, according to the histogram conventions used within
the Higgs2Tau group. All other histograms remain the same. The macro iterates only
through one level of folders. These folders are expected to contain only histograms.
Function arguments are:
armed : update rescaled histograms in file
scale : scale tp be applied
filename : input file that is supposed to host the histograms to be scaled
pattern : the pattern that the histograms to be scale should fullfill; in case
that the pattern is an empty string all patterns that follow the naming
conventions used throughout the Higgs2Tau group are searched for.
*/
int
match(const char *string, const char *pattern)
{
int status;
regex_t re;
if(regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB) != 0) {
return 0; /* report error */
}
status = regexec(&re, string, 0, NULL, 0);
regfree(&re);
if (status != 0) {
return 0 ; /* report error */
}
return 1 ;
}
bool
matchSignal(const char* histName,const char *iExprMatch)
{
return (match(histName, iExprMatch));
}
std::vector<std::string>
signalList(const char* dirName="", const char* pattern="",const char* iExprMatch="", unsigned int debug=0)
{
std::vector<std::string> histnames;
TIter next(gDirectory->GetListOfKeys());
TKey* iobj;
unsigned int idx=0;
while((iobj = (TKey*)next())){
if(iobj->IsFolder()) continue;
if(debug>2){ std::cout << "[" << ++idx << "] ...Found object: " << iobj->GetName() << " of type: " << iobj->GetClassName() << std::endl; }
std::string fullpath(dirName);
fullpath += fullpath == std::string("") ? "" : "/"; fullpath += iobj->GetName();
// why does \\w*_\\d+ not work to catch them all?!?
if(std::string(pattern).empty() && matchSignal(iobj->GetName(),iExprMatch)){
histnames.push_back(fullpath);
}
else if(!std::string(pattern).empty() && match(iobj->GetName(), (char*)pattern)){
histnames.push_back(fullpath);
}
}
return histnames;
}
void decoupleShapes(bool armed, TString iExprMatch,TString iExprRep, const char* filename, const char* pattern="", unsigned int debug=0)
{
std::vector<std::string> histnames; histnames.clear();
if( debug>0 ){
std::cout << "file = " << filename << std::endl;
std::cout << "old = " << iExprMatch.Data() << std::endl;
std::cout << "new = " << iExprRep .Data() << std::endl;
std::cout << "armed = " << armed << std::endl;
}
TFile* file = new TFile(filename, "update");
TIter nextDirectory(file->GetListOfKeys());
std::vector<std::string> buffer;
TKey* idir;
while((idir = (TKey*)nextDirectory())){
buffer.clear();
if( idir->IsFolder() ){
file->cd(); // make sure to start in directory head
if( debug>0 ){ std::cout << "Found directory: " << idir->GetName() << std::endl; }
if( file->GetDirectory(idir->GetName()) ){
file->cd(idir->GetName()); // change to sub-directory
buffer = signalList(idir->GetName(), pattern,iExprMatch.Data(), debug);
}
// append to the vector of histograms to be rescaled
for(std::vector<std::string>::const_iterator elem=buffer.begin(); elem!=buffer.end(); ++elem){
histnames.push_back(*elem);
}
if(debug>1){
std::cout << "added " << buffer.size() << " elements to histnames [" << histnames.size() << "] for directory " << idir->GetName() << std::endl;
}
}
}
// pick up files which are not kept in an extra folder
file->cd(); buffer.clear();
buffer = signalList("", pattern,iExprMatch.Data(), debug);
// append to the vector of histograms to be rescaled
for(std::vector<std::string>::const_iterator elem=buffer.begin(); elem!=buffer.end(); ++elem){
histnames.push_back(*elem);
}
if(debug>1){
std::cout << "added " << buffer.size() << " elements to histnames [" << histnames.size() << "] for file head" << std::endl;
}
for(std::vector<std::string>::const_iterator hist=histnames.begin(); hist!=histnames.end(); ++hist){
file->cd();
TH1F* h = (TH1F*)file->Get(hist->c_str());
std::string histName;
if(hist->find("/")!=std::string::npos){
histName = hist->substr(hist->find("/")+1);
}
else{
histName = *hist;
}
TH1F* hout = (TH1F*)h->Clone(TString(h->GetName()).ReplaceAll(iExprMatch,iExprRep));
if(debug>1){
std::cout << "...folder : " << hist->substr(0, hist->find("/")).c_str() << std::endl;
std::cout << "...histogram : " << hout->GetName () << " / " << hist->c_str() << std::endl;
}
hout->SetTitle(hout->GetName());
if(debug>1){
std::cout << "...new name : " << hout->GetName() << std::endl;
std::cout << "...new title : " << hout->GetTitle() << std::endl;
}
if(armed){
if(hist->find("/")!=std::string::npos){
file->cd(hist->substr(0, hist->find("/")).c_str());
}
else{
file->cd();
}
std::cout << "writing to file: " << hout->GetName() << " -- " << hist->substr(hist->find("/")+1).c_str() << std::endl;
hout->Write();
}
}
file->Close();
return;
}