|
10 | 10 | #include "CombineTools/interface/Utilities.h" |
11 | 11 | #include "CombineTools/interface/HttSystematics.h" |
12 | 12 | #include "CombinePdfs/interface/MorphFunctions.h" |
| 13 | +#include "CombineTools/interface/BinByBin.h" |
13 | 14 |
|
14 | 15 | using namespace std; |
15 | 16 |
|
16 | 17 | int main() { |
17 | 18 | ch::CombineHarvester cb; |
18 | | - |
19 | 19 | // cb.SetVerbosity(1); |
20 | 20 |
|
21 | 21 | typedef vector<pair<int, string>> Categories; |
@@ -103,7 +103,7 @@ int main() { |
103 | 103 | {0, "tauTau_1jet_high_mediumhiggs"}, {1, "tauTau_1jet_high_highhiggs"}, |
104 | 104 | {2, "tauTau_vbf"}}; |
105 | 105 |
|
106 | | - vector<string> masses = ch::MassesFromRange("110-145:5"); |
| 106 | + vector<string> masses = ch::ValsFromRange("110:145|5"); |
107 | 107 |
|
108 | 108 | cout << ">> Creating processes and observations...\n"; |
109 | 109 | for (string era : {"7TeV", "8TeV"}) { |
@@ -145,117 +145,67 @@ int main() { |
145 | 145 | cout << ">> Scaling signal process rates...\n"; |
146 | 146 | map<string, TGraph> xs; |
147 | 147 | // Get the table of H->tau tau BRs vs mass |
148 | | - ch::ParseTable(&xs, "input/xsecs_brs/htt_YR3.txt", {"htt"}); |
| 148 | + xs["htt"] = ch::TGraphFromTable("input/xsecs_brs/htt_YR3.txt", "mH", "br"); |
149 | 149 | for (string const& e : {"7TeV", "8TeV"}) { |
150 | 150 | for (string const& p : sig_procs) { |
151 | 151 | // Get the table of xsecs vs mass for process "p" and era "e": |
152 | | - ch::ParseTable(&xs, "data/xsecs_brs/"+p+"_"+e+"_YR3.txt", {p+"_"+e}); |
| 152 | + xs[p+"_"+e] = ch::TGraphFromTable("input/xsecs_brs/"+p+"_"+e+"_YR3.txt", "mH", "xsec"); |
153 | 153 | cout << ">>>> Scaling for process " << p << " and era " << e << "\n"; |
154 | 154 | cb.cp().process({p}).era({e}).ForEachProc([&](ch::Process *proc) { |
155 | | - ch::ScaleProcessRate(proc, &xs, p+"_"+e, "htt"); |
| 155 | + double m = boost::lexical_cast<double>(proc->mass()); |
| 156 | + proc->set_rate(proc->rate() * xs[p+"_"+e].Eval(m) * xs["htt"].Eval(m)); |
156 | 157 | }); |
157 | 158 | } |
158 | 159 | } |
159 | | - ch::ParseTable(&xs, "input/xsecs_brs/hww_over_htt.txt", {"hww_over_htt"}); |
| 160 | + xs["hww_over_htt"] = ch::TGraphFromTable("input/xsecs_brs/hww_over_htt.txt", "mH", "ratio"); |
160 | 161 | for (string const& e : {"7TeV", "8TeV"}) { |
161 | 162 | for (string const& p : {"ggH", "qqH"}) { |
162 | 163 | cb.cp().channel({"em"}).process({p+"_hww125"}).era({e}) |
163 | 164 | .ForEachProc([&](ch::Process *proc) { |
164 | | - ch::ScaleProcessRate(proc, &xs, p+"_"+e, "htt", "125"); |
165 | | - ch::ScaleProcessRate(proc, &xs, "hww_over_htt", "", "125"); |
| 165 | + proc->set_rate(proc->rate() * xs[p+"_"+e].Eval(125.) * xs["htt"].Eval(125.)); |
| 166 | + proc->set_rate(proc->rate() * xs["hww_over_htt"].Eval(125.)); |
166 | 167 | }); |
167 | 168 | } |
168 | 169 | } |
169 | 170 |
|
170 | | - cout << ">> Merging bin errors...\n"; |
171 | | - ch::CombineHarvester cb_et = move(cb.cp().channel({"et"})); |
172 | | - for (string era : {"7TeV", "8TeV"}) { |
173 | | - cb_et.cp().era({era}).bin_id({1, 2}).process({"ZL", "ZJ", "QCD", "W"}) |
174 | | - .MergeBinErrors(0.1, 0.5); |
175 | | - cb_et.cp().era({era}).bin_id({3, 5}).process({"W"}) |
176 | | - .MergeBinErrors(0.1, 0.5); |
177 | | - } |
178 | | - cb_et.cp().era({"7TeV"}).bin_id({6}).process({"ZL", "ZJ", "W", "ZTT"}) |
179 | | - .MergeBinErrors(0.1, 0.5); |
180 | | - cb_et.cp().era({"8TeV"}).bin_id({7}).process({"ZL", "ZJ", "W", "ZTT"}) |
181 | | - .MergeBinErrors(0.1, 0.5); |
182 | | - cb_et.cp().era({"8TeV"}).bin_id({6}).process({"ZL", "ZJ", "W"}) |
183 | | - .MergeBinErrors(0.1, 0.5); |
184 | | - |
185 | | - ch::CombineHarvester cb_mt = move(cb.cp().channel({"mt"})); |
186 | | - for (string era : {"7TeV", "8TeV"}) { |
187 | | - cb_mt.cp().era({era}).bin_id({1, 2, 3, 4}).process({"W", "QCD"}) |
188 | | - .MergeBinErrors(0.1, 0.5); |
189 | | - } |
190 | | - cb_mt.cp().era({"7TeV"}).bin_id({5}).process({"W"}) |
191 | | - .MergeBinErrors(0.1, 0.5); |
192 | | - cb_mt.cp().era({"7TeV"}).bin_id({6}).process({"W", "ZTT"}) |
193 | | - .MergeBinErrors(0.1, 0.5); |
194 | | - cb_mt.cp().era({"8TeV"}).bin_id({5, 6}).process({"W"}) |
195 | | - .MergeBinErrors(0.1, 0.5); |
196 | | - cb_mt.cp().era({"8TeV"}).bin_id({7}).process({"W", "ZTT"}) |
197 | | - .MergeBinErrors(0.1, 0.5); |
198 | | - |
199 | | - ch::CombineHarvester cb_em = move(cb.cp().channel({"em"})); |
200 | | - for (string era : {"7TeV", "8TeV"}) { |
201 | | - cb_em.cp().era({era}).bin_id({1, 3}).process({"Fakes"}) |
202 | | - .MergeBinErrors(0.1, 0.5); |
203 | | - } |
204 | | - cb_em.cp().era({"7TeV"}).bin_id({4}).process({"Fakes", "EWK", "Ztt"}) |
205 | | - .MergeBinErrors(0.1, 0.5); |
206 | | - cb_em.cp().era({"8TeV"}).bin_id({5}).process({"Fakes", "EWK", "Ztt"}) |
207 | | - .MergeBinErrors(0.1, 0.5); |
208 | | - cb_em.cp().era({"8TeV"}).bin_id({4}).process({"Fakes", "EWK"}) |
209 | | - .MergeBinErrors(0.1, 0.5); |
210 | | - |
211 | | - ch::CombineHarvester cb_ee_mm = move(cb.cp().channel({"ee", "mm"})); |
212 | | - for (string era : {"7TeV", "8TeV"}) { |
213 | | - cb_ee_mm.cp().era({era}).bin_id({1, 3, 4}) |
214 | | - .process({"ZTT", "ZEE", "ZMM", "TTJ"}) |
215 | | - .MergeBinErrors(0.0, 0.5); |
216 | | - } |
217 | | - |
218 | | - ch::CombineHarvester cb_tt = move(cb.cp().channel({"tt"})); |
219 | | - cb_tt.cp().bin_id({0, 1, 2}).era({"8TeV"}).process({"ZTT", "QCD"}) |
220 | | - .MergeBinErrors(0.1, 0.5); |
221 | | - |
222 | | - cout << ">> Generating bbb uncertainties...\n"; |
223 | | - cb_mt.cp().bin_id({0, 1, 2, 3, 4}).process({"W", "QCD"}) |
224 | | - .AddBinByBin(0.1, true, &cb); |
225 | | - cb_mt.cp().era({"7TeV"}).bin_id({5}).process({"W"}) |
226 | | - .AddBinByBin(0.1, true, &cb); |
227 | | - cb_mt.cp().era({"7TeV"}).bin_id({6}).process({"W", "ZTT"}) |
228 | | - .AddBinByBin(0.1, true, &cb); |
229 | | - cb_mt.cp().era({"8TeV"}).bin_id({5, 6}).process({"W"}) |
230 | | - .AddBinByBin(0.1, true, &cb); |
231 | | - cb_mt.cp().era({"8TeV"}).bin_id({7}).process({"W", "ZTT"}) |
232 | | - .AddBinByBin(0.1, true, &cb); |
233 | | - |
234 | | - cb_et.cp().bin_id({1, 2}).process({"ZL", "ZJ", "QCD", "W"}) |
235 | | - .AddBinByBin(0.1, true, &cb); |
236 | | - cb_et.cp().bin_id({3, 5}).process({"W"}) |
237 | | - .AddBinByBin(0.1, true, &cb); |
238 | | - cb_et.cp().era({"7TeV"}).bin_id({6}).process({"ZL", "ZJ", "W", "ZTT"}) |
239 | | - .AddBinByBin(0.1, true, &cb); |
240 | | - cb_et.cp().era({"8TeV"}).bin_id({7}).process({"ZL", "ZJ", "W", "ZTT"}) |
241 | | - .AddBinByBin(0.1, true, &cb); |
242 | | - cb_et.cp().era({"8TeV"}).bin_id({6}).process({"ZL", "ZJ", "W"}) |
243 | | - .AddBinByBin(0.1, true, &cb); |
244 | | - |
245 | | - cb_em.cp().bin_id({1, 3}).process({"Fakes"}) |
246 | | - .AddBinByBin(0.1, true, &cb); |
247 | | - cb_em.cp().era({"7TeV"}).bin_id({4}).process({"Fakes", "EWK", "Ztt"}) |
248 | | - .AddBinByBin(0.1, true, &cb); |
249 | | - cb_em.cp().era({"8TeV"}).bin_id({5}).process({"Fakes", "EWK", "Ztt"}) |
250 | | - .AddBinByBin(0.1, true, &cb); |
251 | | - cb_em.cp().era({"8TeV"}).bin_id({4}).process({"Fakes", "EWK"}) |
252 | | - .AddBinByBin(0.1, true, &cb); |
253 | | - |
254 | | - cb_ee_mm.cp().bin_id({1, 3, 4}).process({"ZTT", "ZEE", "ZMM", "TTJ"}) |
255 | | - .AddBinByBin(0.0, true, &cb); |
256 | | - |
257 | | - cb_tt.cp().bin_id({0, 1, 2}).era({"8TeV"}).process({"QCD", "ZTT"}) |
258 | | - .AddBinByBin(0.1, true, &cb); |
| 171 | + cout << ">> Merging bin errors and generating bbb uncertainties...\n"; |
| 172 | + |
| 173 | + auto bbb = ch::BinByBinFactory() |
| 174 | + .SetAddThreshold(0.1) |
| 175 | + .SetMergeThreshold(0.5) |
| 176 | + .SetFixNorm(true); |
| 177 | + |
| 178 | + ch::CombineHarvester cb_et = cb.cp().channel({"et"}); |
| 179 | + bbb.MergeAndAdd(cb_et.cp().era({"7TeV"}).bin_id({1, 2}).process({"ZL", "ZJ", "QCD", "W"}), cb); |
| 180 | + bbb.MergeAndAdd(cb_et.cp().era({"7TeV"}).bin_id({3, 5}).process({"W"}), cb); |
| 181 | + bbb.MergeAndAdd(cb_et.cp().era({"8TeV"}).bin_id({1, 2}).process({"ZL", "ZJ", "QCD", "W"}), cb); |
| 182 | + bbb.MergeAndAdd(cb_et.cp().era({"8TeV"}).bin_id({3, 5}).process({"W"}), cb); |
| 183 | + bbb.MergeAndAdd(cb_et.cp().era({"7TeV"}).bin_id({6}).process({"ZL", "ZJ", "W", "ZTT"}), cb); |
| 184 | + bbb.MergeAndAdd(cb_et.cp().era({"8TeV"}).bin_id({6}).process({"ZL", "ZJ", "W"}), cb); |
| 185 | + bbb.MergeAndAdd(cb_et.cp().era({"8TeV"}).bin_id({7}).process({"ZL", "ZJ", "W", "ZTT"}), cb); |
| 186 | + |
| 187 | + ch::CombineHarvester cb_mt = cb.cp().channel({"mt"}); |
| 188 | + bbb.MergeAndAdd(cb_mt.cp().era({"7TeV"}).bin_id({1, 2, 3, 4}).process({"W", "QCD"}), cb); |
| 189 | + bbb.MergeAndAdd(cb_mt.cp().era({"8TeV"}).bin_id({1, 2, 3, 4}).process({"W", "QCD"}), cb); |
| 190 | + bbb.MergeAndAdd(cb_mt.cp().era({"7TeV"}).bin_id({5}).process({"W"}), cb); |
| 191 | + bbb.MergeAndAdd(cb_mt.cp().era({"7TeV"}).bin_id({6}).process({"W", "ZTT"}), cb); |
| 192 | + bbb.MergeAndAdd(cb_mt.cp().era({"8TeV"}).bin_id({5, 6}).process({"W"}), cb); |
| 193 | + bbb.MergeAndAdd(cb_mt.cp().era({"8TeV"}).bin_id({7}).process({"W", "ZTT"}), cb); |
| 194 | + |
| 195 | + ch::CombineHarvester cb_em = cb.cp().channel({"em"}); |
| 196 | + bbb.MergeAndAdd(cb_em.cp().era({"7TeV"}).bin_id({1, 3}).process({"Fakes"}), cb); |
| 197 | + bbb.MergeAndAdd(cb_em.cp().era({"8TeV"}).bin_id({1, 3}).process({"Fakes"}), cb); |
| 198 | + bbb.MergeAndAdd(cb_em.cp().era({"7TeV"}).bin_id({4}).process({"Fakes", "EWK", "Ztt"}), cb); |
| 199 | + bbb.MergeAndAdd(cb_em.cp().era({"8TeV"}).bin_id({5}).process({"Fakes", "EWK", "Ztt"}), cb); |
| 200 | + bbb.MergeAndAdd(cb_em.cp().era({"8TeV"}).bin_id({4}).process({"Fakes", "EWK"}), cb); |
| 201 | + |
| 202 | + ch::CombineHarvester cb_tt = cb.cp().channel({"tt"}); |
| 203 | + bbb.MergeAndAdd(cb_tt.cp().era({"8TeV"}).bin_id({0, 1, 2}).process({"ZTT", "QCD"}), cb); |
| 204 | + |
| 205 | + bbb.SetAddThreshold(0.); // ee and mm use a different threshold |
| 206 | + ch::CombineHarvester cb_ll = cb.cp().channel({"ee", "mm"}); |
| 207 | + bbb.MergeAndAdd(cb_ll.cp().era({"7TeV"}).bin_id({1, 3, 4}).process({"ZTT", "ZEE", "ZMM", "TTJ"}), cb); |
| 208 | + bbb.MergeAndAdd(cb_ll.cp().era({"8TeV"}).bin_id({1, 3, 4}).process({"ZTT", "ZEE", "ZMM", "TTJ"}), cb); |
259 | 209 |
|
260 | 210 | cout << ">> Setting standardised bin names...\n"; |
261 | 211 | ch::SetStandardBinNames(cb); |
@@ -303,30 +253,30 @@ int main() { |
303 | 253 | string folder = "output/sm_cards_morphed"; |
304 | 254 | boost::filesystem::create_directories(folder); |
305 | 255 |
|
| 256 | + TFile output((folder + "/htt.input.root").c_str(), |
| 257 | + "RECREATE"); |
306 | 258 | for (string chn : chns) { |
307 | | - TFile output((folder + "/htt_" + chn + ".input.root").c_str(), |
308 | | - "RECREATE"); |
309 | | - // auto bins = cb.cp().channel({chn}).bin_set(); |
310 | | - // for (auto b : bins) { |
311 | | - // for (auto m : masses) { |
312 | | - // cout << ">> Writing datacard for bin: " << b << " and mass: " << m |
313 | | - // << "\r" << flush; |
314 | | - // cb.cp().channel({chn}).bin({b}).mass({m, "*"}).WriteDatacard( |
315 | | - // folder+"/"+b + "_" + m + ".txt", output); |
316 | | - // } |
317 | | - // } |
318 | | - cb.cp().channel({chn}).mass({"125", "*"}).WriteDatacard( |
319 | | - folder+"/htt_" + chn + "_125.txt", output); |
320 | | - output.Close(); |
| 259 | + boost::filesystem::create_directories(folder+"/"+chn); |
| 260 | + //Use CH to create combined card for each channel |
| 261 | + cb.cp().channel({chn}).mass({"*"}).WriteDatacard( |
| 262 | + folder + "/" + chn + "/combinedCard.txt", output); |
| 263 | + auto bins = cb.cp().channel({chn}).bin_set(); |
| 264 | + for (auto b : bins) { |
| 265 | + cout << ">> Writing datacard for bin: " << b << "\r" << flush; |
| 266 | + //Also print individual datacards for each category of each channel |
| 267 | + boost::filesystem::create_directories(folder+"/"+chn); |
| 268 | + cb.cp().channel({chn}).bin({b}).mass({"*"}).WriteDatacard( |
| 269 | + folder + "/" + chn + "/" + b + ".txt", output); |
| 270 | + //Also print individual datacards for each category of each channel in the combined directory |
| 271 | + boost::filesystem::create_directories(folder+"/cmb"); |
| 272 | + cb.cp().channel({chn}).bin({b}).mass({"*"}).WriteDatacard( |
| 273 | + folder + "/cmb/"+ b + ".txt", output); |
| 274 | + } |
321 | 275 | } |
322 | | - TFile output((folder + "/htt_combined.input.root").c_str(), |
323 | | - "RECREATE"); |
324 | | - cb.cp().mass({"125", "*"}).WriteDatacard( |
325 | | - folder+"/htt_combined_125.txt", output); |
| 276 | + //Use CH to create combined card for full combination |
| 277 | + cb.cp().mass({"*"}).WriteDatacard( |
| 278 | + folder + "/cmb/combinedCard.txt", output); |
326 | 279 | output.Close(); |
327 | 280 | cout << "\n>> Done!\n"; |
328 | 281 | } |
329 | | - |
330 | | - |
331 | | - |
332 | 282 | } |
0 commit comments