Asking for the total systematic... May be the current file does not support the asymmetric break-down yet. Let's try the good old approach and load the total sys histogram
Not even the old approach lead to something fruitful... Lets forget it and reset everything
Some other systematic is asked for... Failure
As well as for the high-eta range.
The histogram is simply not loaded which is fine since only the scale-factor is required
10 {
11 const unsigned int EfficiencyScaleFactor::m_warningLimit = 10;
12 EfficiencyScaleFactor::EfficiencyScaleFactor(std::shared_ptr<EfficiencyScaleFactor> nominal,
13 const MuonEfficiencyScaleFactors& ref_tool,
14 const std::string&
file,
15 const std::string& time_unit,
16 const std::string& syst_name,
17 int syst_type_bitmap):
18 m_measurement(ref_tool.measurement()),
19 m_syst_name(syst_name),
20 m_is_up(syst_type_bitmap & EffiCollection::UpVariation),
21 m_is_lowpt(syst_type_bitmap & EffiCollection::JPsiAnalysis),
22 m_respond_to_kineDepSyst(syst_type_bitmap & EffiCollection::PtDependent),
23 m_separateBinSyst(syst_type_bitmap & EffiCollection::UnCorrelated),
24 m_sf(),
25 m_eff(),
26 m_mc_eff(),
27
28 m_sf_decor(
std::make_unique<
FloatDecorator>(ref_tool.sf_decoration()+ (m_syst_name.
empty()?
"" :
"_"+ m_syst_name + (m_is_up?
"_1UP":
"_1DN")))),
29 m_eff_decor(
std::make_unique<
FloatDecorator>(ref_tool.data_effi_decoration()+ (m_syst_name.
empty()?
"" :
"_"+ m_syst_name + (m_is_up?
"_1UP":
"_1DN")))),
30 m_mc_eff_decor(
std::make_unique<
FloatDecorator>(ref_tool.mc_effi_decoration()+ (m_syst_name.
empty()?
"" :
"_"+ m_syst_name + (m_is_up?
"_1UP":
"_1DN")))),
31 m_sf_rep_decor(
std::make_unique<FloatVectorDecorator>(ref_tool.sf_replica_decoration()+ (m_syst_name.
empty()?
"" :
"_"+ m_syst_name + (m_is_up?
"_1UP":
"_1DN")))),
32 m_eff_rep_decor(
std::make_unique<FloatVectorDecorator>(ref_tool.data_effi_replica_decoration()+ (m_syst_name.
empty()?
"" :
"_"+ m_syst_name + (m_is_up?
"_1UP":
"_1DN")))),
33 m_mc_eff_rep_decor(
std::make_unique<FloatVectorDecorator>(ref_tool.mc_effi_replica_deocration()+ (m_syst_name.
empty()?
"" :
"_"+ m_syst_name + (m_is_up?
"_1UP":
"_1DN")))),
34
35 m_sf_KineDepsys(),
36 m_sf_replicas(),
37 m_eff_replicas(),
38 m_mc_eff_replicas(),
39 m_NominalFallBack(nominal),
40 m_SystematicBin(-1),
41 m_default_eff(1.),
42 m_default_eff_ttva(1.),
43 m_warnsPrinted(0),
44 m_firstRun(1),
45 m_lastRun(999999){
46
47 if (ref_tool.measurement() == MuonEfficiencyType::Iso){
48 dRJetAxisHandler::set_close_jet_decorator(ref_tool.close_by_jet_decoration());
49 dRJetAxisHandler::set_use_2D_sf(ref_tool.use_2D_iso_corrections());
50 }
51
52 std::unique_ptr<TFile>
f (TFile::Open(
file.c_str(),
"READ"));
53 if (!f || !
f->IsOpen()) {
54 Error("EfficiencyScaleFactor", "Unable to open file %s", file.c_str());
55 return;
56 }
57
58 m_eff = ReadHistFromFile(
this,
"Eff",
f.get(), time_unit);
59 m_mc_eff = ReadHistFromFile(
this,
"MC_Eff",
f.get(), time_unit);
60 m_sf = ReadHistFromFile(
this,
"SF",
f.get(), time_unit);
62 if (syst_name.empty())
return;
63
64
66 m_default_eff = 2.;
67 m_default_eff_ttva = 1. + 1.e-9;
68 } else {
69 m_default_eff = 0.;
70 m_default_eff_ttva = 1. - 1.e-9;
71 }
72 std::function<void(std::unique_ptr<HistHandler>&,
const std::string& )> syst_loader = [
this, &
f, &time_unit, &syst_type_bitmap] (std::unique_ptr<HistHandler>& nominal,
const std::string& hist_type) {
73 if(!nominal) return;
74 std::unique_ptr<HistHandler>
sys = ReadHistFromFile(
this, Form(
"%s_%s_%s", hist_type.c_str() ,
75 m_syst_name.c_str(),
76 (syst_type_bitmap & EffiCollection::Symmetric ? "SYM" : (m_is_up ? "1UP" : "1DN")) ),
78 if (sys) {
79 for (
int i = 1;
i <= nominal->nBins(); ++
i) {
80 double content = nominal->GetBinContent(i);
81 double variation = (IsUpVariation() ? 1. : -1.)*
sys->GetBinContent(i);
82 nominal->SetBinContent(i,content + variation);
83 }
84 return;
85 }
89 if (m_syst_name == "SYS"){
90 std::unique_ptr<HistHandler> old_sys = ReadHistFromFile(
this, hist_type +
"_sys",
f.get(), time_unit);
92 if (!old_sys){
93 nominal.reset();
94 return;
95 }
96
97 for (
int i = 1;
i<= nominal->nBins(); ++
i) {
98 nominal->SetBinContent(i, nominal->GetBinContent(i) + (IsUpVariation() ? 1. : -1.)*old_sys->GetBinContent(i));
99 }
100 }
102 else if (m_syst_name == "STAT") {
103 for (
int i = 1;
i<= nominal->nBins(); ++
i) {
104 nominal->SetBinContent(i, nominal->GetBinContent(i) + (IsUpVariation() ? 1. : -1.)*nominal->GetBinError(i));
105 }
106 }
108 else if (m_syst_name == "PTDEPENDENCY"){
109 return;
110 }
112 else{
113 Error(
"EfficiencyScaleFactor()",
"Failed to load sytstematic variation %s for measurement %s and histo-type %s", sysname(
true).c_str(),
114 EfficiencyTypeName(m_measurement).c_str(),
115 hist_type.c_str());
116 nominal.reset();
117 }
118 };
120 syst_loader(m_sf,"SF");
121 syst_loader(m_eff,"Eff");
122 syst_loader(m_mc_eff,"MC_Eff");
123
125 if (m_is_lowpt || (
file == ref_tool.filename_HighEta() && ref_tool.filename_HighEta() != ref_tool.filename_Central()) ||
126 (
file == ref_tool.filename_Calo() && ref_tool.filename_Calo() != ref_tool.filename_Central())) m_respond_to_kineDepSyst =
false;
128
130 if (!m_respond_to_kineDepSyst){
131 return;
132 }
133
134 if (m_measurement == MuonEfficiencyType::BadMuonVeto) {
135 TDirectory* SystDir = nullptr;
136 f->GetObject((
"KinematicSystHandler_" + time_unit).c_str(), SystDir);
138 if (SystDir) {
139 m_sf_KineDepsys = std::make_unique<BadMuonVetoSystHandler>(SystDir);
140 } else {
142 f->GetObject(
"BadMuonVetoSyst_3Stations", SystDir);
143 TDirectory* SystDir_2Stat = nullptr;
144 f->GetObject(
"BadMuonVetoSyst_2Stations", SystDir_2Stat);
145 m_sf_KineDepsys = std::make_unique<BadMuonVetoSystHandler>(SystDir, SystDir_2Stat);
146 }
147 m_sf_KineDepsys->SetSystematicWeight( IsUpVariation() ? 1 : -1);
148 if (!m_sf_KineDepsys->initialize()){
149 Error(
"EfficiencyScaleFactor()",
"Pt dependent systematic could not be loaded");
150 m_sf_KineDepsys.reset();
151 }
152 if (m_sf_KineDepsys)
153 addSubtool (*m_sf_KineDepsys);
154 return;
155 } else if (m_measurement == MuonEfficiencyType::TTVA){
156 m_sf_KineDepsys = std::make_unique<TTVAClosureSysHandler>(ReadHistFromFile(
this,
"SF_NonClosure_sys",
f.get(),time_unit));
157 if (!m_sf_KineDepsys->initialize()){
158 Error(
"EfficiencyScaleFactor()",
"TTVA non closure systematic could not be loaded.");
159 m_sf_KineDepsys.reset();
160 }
161 else
162 m_sf_KineDepsys->SetSystematicWeight( IsUpVariation() ? 1 : -1);
163 if (m_sf_KineDepsys)
164 addSubtool (*m_sf_KineDepsys);
165 return;
166
167 }
169 m_sf_KineDepsys = std::make_unique<PtKinematicSystHandler>(ReadHistFromFile(
this, Form(
"SF_PtFlatness_1%s", m_is_up?
"UP" :
"DN"),
f.get(), time_unit), ReadHistFromFile(
this,
"SF_PtDep_sys",
f.get(), time_unit));
170
172 if(!m_sf_KineDepsys->initialize()){
173 m_sf_KineDepsys = std::make_unique<PrimodialPtSystematic>(ReadHistFromFile(
this,
"SF_PtDep_sys",
f.get(), time_unit));
174 }
175 m_sf_KineDepsys->SetSystematicWeight( IsUpVariation() ? 1 : -1);
176 addSubtool (*m_sf_KineDepsys);
177 }
178 EfficiencyScaleFactor::EfficiencyScaleFactor(const MuonEfficiencyScaleFactors& ref_tool,
179 const std::string &
file,
180 const std::string &time_unit):
182 ref_tool,
file, time_unit,
"",0){}
183
184 std::string EfficiencyScaleFactor::sysname(bool with_direction) const {
185 return m_syst_name.empty() ? "" : EfficiencyTypeName(m_measurement) + "_" + m_syst_name +(m_is_lowpt ? "_LOWPT" : "") + (with_direction ? (m_is_up ?"__1UP" : "__1DN") :"");
186 }
187 bool EfficiencyScaleFactor::separateBinSyst() const {
188 return m_separateBinSyst;
189 }
190 bool EfficiencyScaleFactor::IsUpVariation() const{
191 return m_is_up;
192 }
193 unsigned int EfficiencyScaleFactor::firstRun() const{
194 return m_firstRun;
195 }
196 unsigned int EfficiencyScaleFactor::lastRun() const{
197 return m_lastRun;
198 }
199 bool EfficiencyScaleFactor::coversRunNumber(
unsigned int run)
const{
200 return m_firstRun <=
run &&
run <= m_lastRun;
201 }
202 void EfficiencyScaleFactor::setFirstLastRun(unsigned int first, unsigned int last){
204 m_lastRun = last;
205 }
206 bool EfficiencyScaleFactor::CheckConsistency() {
207
208 if (!m_sf) {
209 Error(
"EfficiencyScaleFactor()",
"Could not load the SF for measurement %s and systematic %s",EfficiencyTypeName(m_measurement).c_str(), sysname().c_str());
210 return false;
211 }
212 if (m_respond_to_kineDepSyst && !m_sf_KineDepsys->initialize()) {
213 Error(
"EfficiencyScaleFactor()",
"Could not load the SF pt-dependent systematic for %s and systematic %s", EfficiencyTypeName(m_measurement).c_str(), sysname().c_str() );
214 return false;
215 }
216 if (m_NominalFallBack.get() == this) {
217 Error(
"EfficiencyScaleFactor()",
"The EfficiencyScaleFactor %s has itself as Nominal Fall back.", EfficiencyTypeName(m_measurement).c_str());
218 m_NominalFallBack.reset();
219 return false;
220 }
221 if (m_NominalFallBack) {
222 if (!m_NominalFallBack->sysname().empty() || sysname().
empty()){
223 Error(
"EfficiencyScaleFactor()",
"Either nominal is assigned with a fall back (%s) or the nominal fall back is invald(%s).", sysname().c_str(), m_NominalFallBack->sysname().c_str() );
224 return false;
225 }
226 }
228 Error(
"EfficiencyScaleFactor()",
"Invalid run number range. Since the map is ranging from %u to %u.", firstRun(),
lastRun());
229 return false;
230 }
231 std::function<
bool(
const std::unique_ptr<HistHandler>&)> consistent_histo = [](
const std::unique_ptr<HistHandler>&
histo)->
bool{
234 if (!histo) return true;
235 for (
int i = 1;
i <=
histo->nBins(); ++
i){
236 if (std::isnan(
histo->GetBinContent(i)) || std::isinf(
histo->GetBinContent(i))){
237 Error(
"EfficiencyScaleFactor()",
"The %d-th bin %s has not a number (%f)",i,
histo->GetBinName(i).c_str(),
histo->GetBinContent(i));
238 return false;
239 }
240 }
241 return true;
242 };
243 if (!consistent_histo(m_sf)){
244 Error(
"EfficiencyScaleFactor()",
"Invalid scalefactor in %s", sysname().c_str());
245 return false;
246 }
247 if (!consistent_histo(m_eff)){
248 Error(
"EfficiencyScaleFactor()",
"Invalid data-efficiency in %s", sysname().c_str());
249 return false;
250 }
251 if (!consistent_histo(m_mc_eff)){
252 Error(
"EfficiencyScaleFactor()",
"Invalid MC-efficiency in %s", sysname().c_str());
253 return false;
254 }
255 return true;
256 }
257 std::unique_ptr<HistHandler> EfficiencyScaleFactor::ReadHistFromFile(
columnar::ColumnarTool<>* parent,
const std::string& name, TFile* f,
const std::string& time_unit) {
258
259 TH1* hist_from_file = nullptr;
260
261 f->GetObject((name + std::string(
"_") + time_unit).c_str(), hist_from_file);
262
263
264 if (!hist_from_file && time_unit == "All") {
265 f->GetObject(
name.c_str(), hist_from_file);
266 }
267 if (!hist_from_file) {
268 return std::unique_ptr<HistHandler>();
269 }
270 return package_histo(parent, hist_from_file);
271 }
273
274
275 if (!h) return std::unique_ptr<HistHandler>();
276 if (dynamic_cast<TH2Poly*>(h)) {
277 return std::make_unique<HistHandler_TH2Poly>(parent, dynamic_cast<TH2Poly*>(h));
278 }
else if (
h->GetDimension() == 3) {
279 return std::make_unique<HistHandler_TH3>(parent, h);
280 }
else if (
h->GetDimension() == 2) {
281 return std::make_unique<HistHandler_TH2>(parent, h);
282 }
else if (
h->GetDimension() == 1) {
283 return std::make_unique<HistHandler_TH1>(parent, h);
284 }
285 Error(
"EfficiencyScaleFactor",
"Unable to package histo %s (%s) in a known HistHandler",
h->GetName(),
h->IsA()->GetName());
286 return std::unique_ptr<HistHandler>();
287 }
288 int EfficiencyScaleFactor::nBins() const {
289 return m_sf ? m_sf->nBins() : -1;
290 }
291 int EfficiencyScaleFactor::nOverFlowBins() const{
292 return m_sf ? m_sf->nOverFlowBins() : -1;
293 }
294 bool EfficiencyScaleFactor::isOverFlowBin(int b) const{
295 return m_sf ? m_sf->isOverFlowBin(b) : true;
296 }
299 }
301 if (m_separateBinSyst && m_NominalFallBack) {
303 CP::CorrectionCode
cc = m_sf->FindBin(mu, bin);
306 }
307 if (bin != m_SystematicBin) {
308 return m_NominalFallBack->ScaleFactor(mu, SF);
309 }
310 }
311 CP::CorrectionCode
cc = GetContentFromHist(m_sf.get(), mu, SF,
true);
314 }
315
317 if (m_separateBinSyst && m_NominalFallBack && m_eff) {
319 CP::CorrectionCode
cc = m_eff->FindBin(mu, bin);
322 }
323 if (bin != m_SystematicBin) {
324 return m_NominalFallBack->DataEfficiency(mu, Eff);
325 }
326 }
327 CP::CorrectionCode
cc = GetContentFromHist(m_eff.get(), mu, Eff,
true);
330 }
332 if (m_separateBinSyst && m_NominalFallBack && m_mc_eff) {
334 CP::CorrectionCode
cc = m_mc_eff->FindBin(mu, bin);
337 }
338 if (bin != m_SystematicBin) {
339 return m_NominalFallBack->MCEfficiency(mu, Eff);
340 }
341 }
342 CP::CorrectionCode
cc = GetContentFromHist(m_mc_eff.get(), mu, Eff,
false);
345 }
346
348 return GetContentFromHist (Hist,
columnar::MuonId (mu), Eff, add_kine_syst);
349 }
351 Eff = m_default_eff;
352 if (!Hist) {
353 if (m_warnsPrinted < m_warningLimit){
354 Warning("EfficiencyScaleFactor", "Could not find histogram for variation %s and muon with pt=%.4f, eta=%.2f and phi=%.2f, returning %.1f", sysname().c_str(), ptAcc(mu), etaAcc(mu), phiAcc(mu), m_default_eff);
355 ++m_warnsPrinted;
356 }
358 }
359 if (m_measurement == MuonEfficiencyType::TTVA && std::abs(etaAcc(mu)) > 2.5 && std::abs(etaAcc(mu)) <= 2.7 && muonTypeAcc(mu) == xAOD::Muon::MuonType::MuonStandAlone) {
360 if (m_warnsPrinted < m_warningLimit){
361 Info(
"EfficiencyScaleFactor",
"No TTVA sf/efficiency provided for standalone muons with 2.5<|eta|<2.7 for variation %s and muon with pt=%.4f, eta=%.2f and phi=%.2f, returning %.1f", sysname().c_str(), ptAcc(mu), etaAcc(mu), phiAcc(mu), m_default_eff_ttva);
362 ++m_warnsPrinted;
363 }
364 Eff = m_default_eff_ttva;
366 }
368 CP::CorrectionCode
cc = Hist->FindBin(mu, bin);
370 else Eff = Hist->GetBinContent(bin);
371
372 if (add_kine_syst && m_respond_to_kineDepSyst) {
373 return m_sf_KineDepsys->GetKineDependent(mu, Eff);
374 }
376 }
379 CP::CorrectionCode
result = ScaleFactor(mu, sf);
380 (*m_sf_decor)(
mu) = sf;
382 }
384 std::vector<float> replicas(n_replicas);
385 CP::CorrectionCode
result = ScaleFactorReplicas(mu, replicas);
386 (*m_sf_rep_decor)(
mu)= replicas;
388 }
389
392 CP::CorrectionCode
result = DataEfficiency(mu, effi);
393 (*m_eff_decor)(
mu) = effi;
395 }
397 std::vector<float> replicas(n_replicas);
398 CP::CorrectionCode
result = DataEfficiencyReplicas(mu, replicas);
399 (*m_eff_rep_decor)(
mu) = replicas;
401 }
404 CP::CorrectionCode
result = MCEfficiency(mu, effi);
405 (*m_mc_eff_decor)(
mu) = effi;
407 }
409 std::vector<float> replicas(n_replicas);
410 CP::CorrectionCode
result = MCEfficiencyReplicas(mu, replicas);
411 (*m_mc_eff_rep_decor)(
mu) = replicas;
413 }
415 return GetContentReplicasFromHist(m_sf_replicas, mu, SF, true);
416 }
418 return GetContentReplicasFromHist(m_eff_replicas, mu, eff, true);
419 }
421 return GetContentReplicasFromHist(m_mc_eff_replicas, mu, eff, false);
422 }
423 CP::CorrectionCode EfficiencyScaleFactor::GetContentReplicasFromHist(EfficiencyScaleFactor::SFReplicaVec &replicas,
const xAOD::Muon& mu, std::vector<float> & SF,
bool add_kine_syst) {
424 if (replicas.size() !=
SF.size()) GenerateReplicas(
SF.size(), 1000. *
mu.phi() +
mu.eta());
426 if (m_measurement == MuonEfficiencyType::TTVA && std::abs(
mu.eta()) > 2.5 && std::abs(
mu.eta()) <= 2.7 &&
mu.muonType() == xAOD::Muon::MuonType::MuonStandAlone) {
427 if (m_warnsPrinted < m_warningLimit){
428 Info(
"EfficiencyScaleFactor",
"No TTVA sf/efficiency provided for standalone muons with 2.5<|eta|<2.7 for variation %s and muon with pt=%.4f, eta=%.2f and phi=%.2f, returning %.1f", sysname().c_str(),
mu.pt(),
mu.eta(),
mu.phi(), m_default_eff_ttva);
429 ++m_warnsPrinted;
430 }
432 r = m_default_eff_ttva;
434 }
436 float extra_sys = 1;
437 if (add_kine_syst && m_respond_to_kineDepSyst) {
438 CP::CorrectionCode
cc = m_sf_KineDepsys->GetKineDependent(mu, extra_sys);
440 }
441
442 CP::CorrectionCode
res = (*replicas.begin())->FindBin(mu, bin);
444 else {
445 for (
size_t k = 0;
k <
SF.size();
k++) {
446 SF[
k] = replicas.at(k)->GetBinContent(bin) * extra_sys;
447 }
448 }
450 }
451 void EfficiencyScaleFactor::GenerateReplicas(int nrep, int seed) {
452 GenerateReplicasFromHist(m_eff.get(), nrep, seed, m_eff_replicas);
453 GenerateReplicasFromHist(m_sf.get(), nrep, seed, m_sf_replicas);
454 GenerateReplicasFromHist(m_mc_eff.get(), nrep, seed, m_mc_eff_replicas);
455 }
456 void EfficiencyScaleFactor::GenerateReplicasFromHist(
HistHandler*
h,
int nrep,
int seed, EfficiencyScaleFactor::SFReplicaVec &replicas) {
457 if (!h) return;
458 TRandom3 Rndm(seed);
459 replicas.clear();
460 replicas.reserve(nrep);
462 for (
int t = 0;
t < nrep;
t++) {
463 replicas.push_back(package_histo(
this,
h->GetHist()));
464 HistHandler* replica = replicas.back().get();
466 replica->SetBinContent(bin, Rndm.Gaus(
h->GetBinContent(bin),
h->GetBinError(bin)));
467 }
468 }
469 }
470
471 bool EfficiencyScaleFactor::SetSystematicBin(
int bin) {
472 if (m_syst_name.empty()) return true;
473 if (!m_NominalFallBack) {
474 Error(
"EfficiencyScaleFactor::SetSystematicBin()",
"No fallback has been given for %s", sysname().c_str());
475 return false;
476 }
477 if (!m_separateBinSyst || bin < 1 || bin >
nBins()) {
478 Error(
"EfficiencyScaleFactor::SetSystematicBin()",
"The current bin %i is out of the maximum range %u ", bin,
nBins());
479 return false;
480 }
481 m_SystematicBin =
bin;
482 return true;
483 }
484 std::string EfficiencyScaleFactor::GetBinName(
int bin)
const {
485 if (bin < 1 || bin >
nBins()) {
486 Error(
"EfficiencyScaleFactor::GetBinName()",
"The current bin %i is out of the maximum range %u ", bin,
nBins());
487 return "Out of range";
488 }
489 return m_sf->GetBinName(bin);
490 }
491
492 int EfficiencyScaleFactor::FindBinSF(
const xAOD::Muon & mu)
const {
494 CP::CorrectionCode
cc = m_sf->FindBin(mu, bin);
496 return -1;
497 }
499 }
500
501}
std::pair< std::vector< unsigned int >, bool > res
static const Attributes_t empty
Header file for AthHistogramAlgorithm.
Return value from object correction CP tools.
@ Error
Some error happened during the object correction.
@ OutOfValidityRange
Input object is out of validity range.
@ Ok
The correction was done successfully.
SG::Decorator< float > FloatDecorator
Error
The different types of error that can be flagged in the L1TopoRDO.
const float SF[NF]
Cross sections for Fluor.
ObjectId< MuonDef > MuonId
Muon_v1 Muon
Reference the current persistent version:
setBGCode setTAP setLVL2ErrorBits bool
int run(int argc, char *argv[])