ATLAS Offline Software
Loading...
Searching...
No Matches
dumpNPs.cxx File Reference
#include "CaloGeoHelpers/CaloSampling.h"
#include "AsgTools/AnaToolHandle.h"
#include "EgammaAnalysisInterfaces/IAsgElectronEfficiencyCorrectionTool.h"
#include "ElectronEfficiencyCorrection/AsgElectronEfficiencyCorrectionTool.h"
#include "AsgMessaging/MessageCheck.h"
#include "CreateDummyEl.h"
#include <vector>
#include <map>
#include <tuple>
#include <bitset>
#include <sstream>
#include <type_traits>
#include <cstdlib>
#include <limits>
#include <algorithm>

Go to the source code of this file.

Classes

struct  Domain
struct  NP
struct  Config

Macros

#define MSGSOURCE   "EgEfficiencyCorr_dumpNPs"

Typedefs

using map_t = std::map<NP, std::vector<std::size_t>>

Functions

template<typename... Args>
bool parse_csv_list (std::string val, Args &... args)
bool scanPhaseSpace (Config &config, map_t &affected_bins)
bool displayFindings (const Config &config, const map_t &affected_bins)
bool displayFindings_analysis (const Config &cfg, const map_t &affected_bins)
bool find_boundaries (const Config &cfg, const map_t::mapped_type &affected_bins, Domain &bounds, bool &abs_eta, bool &holes)
int get_run_number (const int year)
int main (int argc, char *argv[])
bool parse_csv_token (const float x, std::vector< float > &bins)
bool parse_csv_token (std::string s, std::vector< int8_t > &flags, const std::vector< float > &edges)

Variables

std::vector< float > eta_edges
std::vector< float > pt_edges
const std::size_t subdiv_eta {5}
const std::size_t subdiv_pt {3}

Macro Definition Documentation

◆ MSGSOURCE

#define MSGSOURCE   "EgEfficiencyCorr_dumpNPs"

Definition at line 23 of file dumpNPs.cxx.

Typedef Documentation

◆ map_t

using map_t = std::map<NP, std::vector<std::size_t>>

Definition at line 58 of file dumpNPs.cxx.

Function Documentation

◆ displayFindings()

bool displayFindings ( const Config & config,
const map_t & affected_bins )

Definition at line 376 of file dumpNPs.cxx.

377{
378 using namespace asg::msgUserCode;
379 for (const auto& s : cfg.systematics) {
380 const NP np{std::get<NP>(s)};
381 const std::string name(std::get<CP::SystematicSet>(s).begin()->basename());
382 Domain bounds{};
383 bool valid{false}, holes{false}, abs_eta{false};
384 auto itr = affected_bins.find(np);
385 if (itr != affected_bins.end()) {
386 valid = find_boundaries(cfg, itr->second, bounds, abs_eta, holes);
387 }
388 if (!valid) {
389 Warning(MSGSOURCE, "%s seems to not affect any bin", name.c_str());
390 continue;
391 }
392 std::string txt(name + " --> ");
393 if (holes) txt += "subdomain of ";
394 txt += bounds.str(abs_eta) + '.';
395 if (!holes) {
396 Info(MSGSOURCE, "%s", txt.c_str());
397 } else {
398 Warning(MSGSOURCE, "%s", txt.c_str());
399 }
400 }
401 return true;
402}
bool find_boundaries(const Config &cfg, const map_t::mapped_type &affected_bins, Domain &bounds, bool &abs_eta, bool &holes)
Definition dumpNPs.cxx:438
@ Info
Definition ZDCMsg.h:20
list valid
Definition calibdata.py:44
std::string str(const bool abs_eta=false) const
Definition dumpNPs.cxx:498
Definition dumpNPs.cxx:34
#define MSGSOURCE
Test code to test ElectronPhotonVariableCorrectionTool Dictionaries.
std::string basename(std::string name)
Definition utils.cxx:207

◆ displayFindings_analysis()

bool displayFindings_analysis ( const Config & cfg,
const map_t & affected_bins )

Definition at line 405 of file dumpNPs.cxx.

406{
407 using namespace asg::msgUserCode;
408
409 std::vector<std::pair<std::string, int>> summary;
410 NP prev{-888, false};
411 for (const auto& kv : affected_bins) {
412 const auto& bins{kv.second};
413 if (bins.empty()) continue;
414 const NP np{kv.first};
415 const bool next{prev.uncorr==np.uncorr && np.index==prev.index+1};
416 prev = np;
417 if (!summary.empty() && next) {
418 std::get<int>(summary.back()) = np.index;
419 continue;
420 }
421 const auto& sys{
422 std::get<CP::SystematicSet>(
423 *std::find_if(
424 cfg.systematics.cbegin(), cfg.systematics.cend(),
425 [=](auto& x){ return std::get<NP>(x) == np; }))};
426 summary.emplace_back(sys.begin()->basename(), -1);
427 }
428 for (const auto& x: summary) {
429 std::string s(" ++ " + std::get<std::string>(x));
430 const int i{std::get<int>(x)};
431 if (i >= 0) s += " to " + std::to_string(i);
432 Info(MSGSOURCE, "%s", s.c_str());
433 }
434 return true;
435}
static const std::vector< std::string > bins
#define x
int index
Definition dumpNPs.cxx:35
bool uncorr
Definition dumpNPs.cxx:36

◆ find_boundaries()

bool find_boundaries ( const Config & cfg,
const map_t::mapped_type & affected_bins,
Domain & bounds,
bool & abs_eta,
bool & holes )

Definition at line 438 of file dumpNPs.cxx.

443{
444 if (affected_bins.empty()) return false;
445 constexpr float inf{std::numeric_limits<float>::max()};
446 constexpr float inf_{std::numeric_limits<float>::lowest()};
447 Domain bAC[2] = {{inf, inf_, inf, inf_}, {inf, inf_, inf, inf_}};
448 auto update = [&](const int side, const auto& dom,
449 const float etamin, const float etamax) {
450 auto& b = bAC[side];
451 b.etamin = std::min(b.etamin, etamin);
452 b.etamax = std::max(b.etamax, etamax);
453 b.ptmin = std::min(b.ptmin, dom.ptmin);
454 b.ptmax = std::max(b.ptmax, dom.ptmax);
455 };
456
457 for (const int bin : affected_bins) {
458 const Domain& dom{cfg.domains.at(bin)};
459 if (dom.etamax > 0.f) update(1, dom, std::max(0.f, dom.etamin), dom.etamax);
460 if (dom.etamin < 0.f) update(0, dom, dom.etamin, std::min(0.f, dom.etamax));
461 }
462
463 holes = false;
464 const int ac{2*(bAC[1].ptmin!=inf) + (bAC[0].ptmin!=inf)};
465 if (ac == 3) {
466 abs_eta = (bAC[0].ptmin == bAC[1].ptmin) && (bAC[0].ptmax == bAC[1].ptmax) &&
467 (std::fabs(bAC[0].etamax + bAC[1].etamin) < 1e-4f) &&
468 (std::fabs(bAC[0].etamin + bAC[1].etamax) < 1e-4f);
469 if (abs_eta) {
470 bounds = bAC[1];
471 } else {
472 holes = true;
473 bounds.etamin = bAC[0].etamin;
474 bounds.etamax = bAC[1].etamax;
475 bounds.ptmin = std::min(bAC[0].ptmin, bAC[1].ptmin);
476 bounds.ptmax = std::min(bAC[0].ptmax, bAC[1].ptmax);
477 }
478 } else if (ac) bounds = bAC[ac - 1];
479 else return false;
480
481 if (!holes) {
482 // Search for overlapping domains not affected by this NP.
483 const std::size_t imax{cfg.domains.size()};
484 auto f = [=](const float x) { return abs_eta? std::fabs(x) : x; };
485 for (std::size_t i{0}; i<imax && !holes; ++i) {
486 if (std::count(affected_bins.cbegin(), affected_bins.cend(), i)) continue;
487 const auto& dom{cfg.domains[i]};
488 holes = (dom.ptmax > bounds.ptmin) &&
489 (dom.ptmin < bounds.ptmax) &&
490 (f(dom.etamax) > bounds.etamin) &&
491 (f(dom.etamin) < bounds.etamax);
492 }
493 }
494 return true;
495}
int imax(int i, int j)
double ptmax
TStreamerInfo * inf
float ptmax
Definition dumpNPs.cxx:28
float etamin
Definition dumpNPs.cxx:28
float ptmin
Definition dumpNPs.cxx:28
float etamax
Definition dumpNPs.cxx:28

◆ get_run_number()

int get_run_number ( const int year)

Definition at line 576 of file dumpNPs.cxx.

577{
578 using namespace asg::msgUserCode;
579 constexpr int random_runs[] = {280423, 302737, 332720, 354826};
580 switch(year) {
581 case 2015: case 2016: case 2017: case 2018:
582 return random_runs[year - 2015];
583 default:
585 "Invalid year specified, it should be between 2015 and 2018.");
586 std::abort();
587 }
588}
Error
The different types of error that can be flagged in the L1TopoRDO.
Definition Error.h:16

◆ main()

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

Definition at line 85 of file dumpNPs.cxx.

86{
87 using namespace asg::msgUserCode;
88
89 #ifdef XAOD_STANDALONE
90 StatusCode::enableFailure();
93 #endif
94
96 //copy negated elements onto end of vector without duplicating the first element (which is zero)
97 std::transform(eta_edges.begin()+1,eta_edges.end(), std::back_inserter(eta_edges),std::negate());
98 //
99 std::sort(eta_edges.begin(), eta_edges.end());
100 std::sort(pt_edges.begin(), pt_edges.end());
101 const bool duplicates_eta{
102 std::adjacent_find(eta_edges.begin(), eta_edges.end()) != eta_edges.end()};
103 const bool duplicates_pt{
104 std::adjacent_find(pt_edges.begin(), pt_edges.end()) != pt_edges.end()};
105 if (duplicates_eta || duplicates_pt) {
106 Error(MSGSOURCE, "Duplicated values in the specified bin edges.");
107 std::abort();
108 }
109
110 // Setup tool using command-line arguments
111 Config cfg;
112 ANA_CHECK( cfg.initialize(argc, argv) );
113 ANA_CHECK( cfg.tool.initialize() );
114
115 // List nuisance parameters for systematics
116 const CP::SystematicSet allsysts(cfg.tool->recommendedSystematics());
117 try {
118 std::set<std::string> recorded;
119 for (const auto& var : allsysts) {
120 std::string name(var.basename());
121 if (!recorded.emplace(name).second) continue;
122 NP np;
123 if (name.find("UncorrUncertainty") != std::string::npos) {
124 np.uncorr = true;
125 } else if (name.find("CorrUncertainty") != std::string::npos) {
126 np.uncorr = false;
127 } else {
128 throw std::invalid_argument("");
129 }
130 np.index = std::stoul(name.substr(name.find("NP") + 2));
131 cfg.systematics.emplace_back(CP::SystematicSet{var}, np);
132 }
133 } catch (std::invalid_argument&) {
134 Error(MSGSOURCE, "The pattern of the SystematicVariation names seems to have changed.");
135 std::abort();
136 }
137 std::sort(cfg.systematics.begin(), cfg.systematics.end(),
138 [](auto& x, auto& y) { return std::get<NP>(x) < std::get<NP>(y); });
139
140 if (cfg.analysis_mode) {
141 for (const int year : {2015, 2016, 2017, 2018}) {
142 map_t affected_bins;
143 cfg.run_number = get_run_number(year);
144 ANA_CHECK( scanPhaseSpace(cfg, affected_bins) );
145 Info(MSGSOURCE, "%s", "");
146 Info(MSGSOURCE, "Relevant nuisance parameters for the year %i:", year);
147 ANA_CHECK( displayFindings_analysis(cfg, affected_bins) );
148 }
149 } else {
150 map_t affected_bins;
151 ANA_CHECK( scanPhaseSpace(cfg, affected_bins) );
152 ANA_CHECK( displayFindings(cfg, affected_bins) );
153 }
154
155 return 0;
156}
#define ANA_CHECK(EXP)
check whether the given expression was successful
#define y
static void enableFailure() noexcept
Class to wrap a set of SystematicVariations.
Tool for accessing xAOD files outside of Athena.
@ kClassAccess
Access auxiliary data using the aux containers.
bool displayFindings(const Config &config, const map_t &affected_bins)
Definition dumpNPs.cxx:376
bool scanPhaseSpace(Config &config, map_t &affected_bins)
Definition dumpNPs.cxx:279
int get_run_number(const int year)
Definition dumpNPs.cxx:576
std::vector< float > pt_edges
Definition dumpNPs.cxx:76
std::vector< float > eta_edges
Definition dumpNPs.cxx:71
std::map< NP, std::vector< std::size_t > > map_t
Definition dumpNPs.cxx:58
bool displayFindings_analysis(const Config &cfg, const map_t &affected_bins)
Definition dumpNPs.cxx:405
list recorded
if USE_PDG_VALUES = True, load PDG value of sin2thetaW and particle masses/widths from parameter dict...
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
StatusCode Init(const char *appname)
Function initialising ROOT/PyROOT for using the ATLAS EDM.
Definition Init.cxx:31

◆ parse_csv_list()

template<typename... Args>
bool parse_csv_list ( std::string val,
Args &... args )

Definition at line 562 of file dumpNPs.cxx.

563{
564 std::replace(val.begin(), val.end(), ',', ' ');
565 std::stringstream ss{val};
566 while (true) {
567 std::conditional_t<(sizeof...(Args)<2), float, std::string> x;
568 ss >> x;
569 if (ss.fail()) break;
570 if (!parse_csv_token(x, args...)) return false;
571 }
572 return ss.eof();
573}
static Double_t ss
bool parse_csv_token(const float x, std::vector< float > &bins)
Definition dumpNPs.cxx:513

◆ parse_csv_token() [1/2]

bool parse_csv_token ( const float x,
std::vector< float > & bins )

Definition at line 513 of file dumpNPs.cxx.

514{
515 bins.push_back(x);
516 return true;
517}

◆ parse_csv_token() [2/2]

bool parse_csv_token ( std::string s,
std::vector< int8_t > & flags,
const std::vector< float > & edges )

Definition at line 520 of file dumpNPs.cxx.

523{
524 const bool accept_aliases{&edges == &eta_edges};
525 if (flags.size() != edges.size() - 1) return false;
526 int alias{0};
527 if (s == "nocrack") alias = 1;
528 else if (s == "barrel") alias = 2;
529 else if (s == "endcap") alias = 3;
530 else if (s == "sym") alias = 4;
531 if (!accept_aliases && alias>0) return false;
532 if (alias>=1 && alias<=3) {
533 for (std::size_t i{0}; i<edges.size()-1; ++i) {
534 const float eta{std::fabs(edges[i])};
535 if (alias==1 && eta>=1.37f && eta<1.52f) flags[i] = -1;
536 if (alias==2 && eta<1.37f) flags[i] = 1;
537 if (alias==3 && eta>1.52f) flags[i] = 1;
538 }
539 return true;
540 } else if (alias == 4) {
541 for (std::size_t i=0;i<edges.size();++i) {
542 if (edges[i] < 0) flags[i] = 2;
543 }
544 return true;
545 }
546 auto pos = s.find("..");
547 if (pos == std::string::npos) return false;
548 std::stringstream ss{s.replace(pos, 2, 1, ' ')};
549 float xmin, xmax;
550 ss >> xmin >> xmax;
551 if (ss.fail() || !(ss >> std::ws).eof()) return false;
552 for (std::size_t i{0}; i<edges.size()-1; ++i) {
553 if (xmin<edges[i+1] && xmax>edges[i] && flags[i]>=0) {
554 flags[i] = 1;
555 }
556 }
557 return true;
558}
Scalar eta() const
pseudorapidity method
double xmax
Definition listroot.cxx:61
double xmin
Definition listroot.cxx:60

◆ scanPhaseSpace()

bool scanPhaseSpace ( Config & config,
map_t & affected_bins )

Definition at line 279 of file dumpNPs.cxx.

280{
281 using namespace asg::msgUserCode;
282
283 static int display_count{-1};
284 if (!++display_count) {
286 "Scanning the eta/pt plane, this will take a bit of time...");
287 }
288
290
291 using RealTool = const AsgElectronEfficiencyCorrectionTool;
292 const auto *asgtool = dynamic_cast<RealTool*>(&*cfg.tool);
293 const std::size_t jmax{subdiv_eta + 1}, kmax{subdiv_pt + 1};
294 const std::size_t dmax{cfg.domains.size()};
295 for (std::size_t d{0}; d<dmax; ++d) {
296 const auto& dom = cfg.domains[d];
297 std::bitset<1024> zero_uncorr{}, nonzero_uncorr{}, expected_uncorr{};
298 std::bitset<256> zero_corr{}, nonzero_corr{};
299 bool multi_np{false};
300 for (std::size_t j{1}; j<jmax; ++j) {
301 const float eta{((jmax-j)*dom.etamin + j*dom.etamax) / jmax};
302 for (std::size_t k{1}; k<kmax; ++k) {
303 const float pt{((kmax-k)*dom.ptmin + k*dom.ptmax) / kmax};
304 ANA_CHECK( getElectrons({{pt, eta}}, cfg.run_number, store) );
305 const xAOD::ElectronContainer* electrons{nullptr};
306 ANA_CHECK( store.retrieve(electrons, "MyElectrons") );
307 const xAOD::Electron& electron{*electrons->at(0)};
308 double sf_nom{}, sf{};
309 ANA_CHECK( cfg.tool->applySystematicVariation({}) );
310 ANA_CHECK( cfg.tool->getEfficiencyScaleFactor(electron, sf_nom) );
311 int vi{asgtool->systUncorrVariationIndex(electron)};
312 expected_uncorr.set(vi);
313 unsigned n_nonzero_uncorr{0};
314 for (const auto& s : cfg.systematics) {
315 const auto& sys = std::get<CP::SystematicSet>(s);
316 ANA_CHECK( cfg.tool->applySystematicVariation(sys) );
317 ANA_CHECK( cfg.tool->getEfficiencyScaleFactor(electron, sf) );
318 const double delta{sf - sf_nom};
319 const NP np{std::get<NP>(s)};
320 if (delta != 0.) {
321 if (np.uncorr) {
322 nonzero_uncorr.set(np.index);
323 ++n_nonzero_uncorr;
324 }
325 else nonzero_corr.set(np.index);
326 } else {
327 if (np.uncorr) zero_uncorr.set(np.index);
328 else zero_corr.set(np.index);
329 }
330 }
331 multi_np = multi_np || (n_nonzero_uncorr > 1);
332 store.clear();
333 }
334 }
335 if (multi_np) {
336 std::string w("several uncorrelated NPs seem to affect the bin at "
337 + dom.str() + ".");
338 Warning(MSGSOURCE, "%s", w.c_str());
339 } else if (nonzero_uncorr.count() > 1) {
340 std::string w{"the binning used for the scan is unadapted at " +
341 dom.str() + " (too coarse?)."};
342 Warning(MSGSOURCE, "%s", w.c_str());
343 }
344 if ((zero_uncorr & nonzero_uncorr).any() ||
345 (zero_corr & nonzero_corr).any()) {
346 std::string w("the binning used for the scan is unadapted at " +
347 dom.str() + " (wrong boundaries?).");
348 Warning(MSGSOURCE, "%s", w.c_str());
349 }
350 if ((nonzero_uncorr!=expected_uncorr) && nonzero_uncorr.any()) {
351 std::string snz, se;
352 for (std::size_t i{0}; i<nonzero_uncorr.size(); ++i) {
353 std::string x{std::to_string(i) + ','};
354 if (nonzero_uncorr[i] && !expected_uncorr[i]) snz += x;
355 if (!nonzero_uncorr[i] && expected_uncorr[i]) se += x;
356 }
357 if (snz.length()) snz.pop_back();
358 if (se.length()) se.pop_back();
359 std::string w{"systUncorrVariationIndex() at " + dom.str() +
360 " indicates different NP(s) than those found in the scan, "
361 "(%s) vs (%s)."};
362 Warning(MSGSOURCE, w.c_str(), se.c_str(), snz.c_str());
363 }
364 for (const auto& s : cfg.systematics) {
365 const NP np{std::get<NP>(s)};
366 const bool impact{
367 np.uncorr? nonzero_uncorr.test(np.index)
368 : nonzero_corr.test(np.index)};
369 if (impact) affected_bins[np].emplace_back(d);
370 }
371 }
372 return true;
373}
StatusCode getElectrons(const std::vector< std::pair< double, double > > &pt_eta, int runNumber, xAOD::TStore &store)
A relatively simple transient store for objects created in analysis.
Definition TStore.h:45
const std::size_t subdiv_pt
Definition dumpNPs.cxx:82
const std::size_t subdiv_eta
Definition dumpNPs.cxx:81
TestStore store
Definition TestStore.cxx:23
ElectronContainer_v1 ElectronContainer
Definition of the current "electron container version".
Electron_v1 Electron
Definition of the current "egamma version".

Variable Documentation

◆ eta_edges

std::vector<float> eta_edges
Initial value:
= {
0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f,
1.15f, 1.2f, 1.3f, 1.37f, 1.52f, 1.6f, 1.65f, 1.7f, 1.8f, 1.9f, 2.0f,
2.1f, 2.2f, 2.3f, 2.37f, 2.4f, 2.47f}

Definition at line 71 of file dumpNPs.cxx.

71 { // eta<0 bins are auto-added in main()
72 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f,
73 1.15f, 1.2f, 1.3f, 1.37f, 1.52f, 1.6f, 1.65f, 1.7f, 1.8f, 1.9f, 2.0f,
74 2.1f, 2.2f, 2.3f, 2.37f, 2.4f, 2.47f};

◆ pt_edges

std::vector<float> pt_edges
Initial value:
= {
45e2f, 7e3f, 1e4f, 15e3f, 2e4f, 25e3f, 3e4f, 35e3f, 4e4f, 45e3f, 5e4f,
6e4f, 8e4f, 15e4f, 25e4f, 5e5f, 1e7f}

Definition at line 76 of file dumpNPs.cxx.

76 { // in MeV
77 45e2f, 7e3f, 1e4f, 15e3f, 2e4f, 25e3f, 3e4f, 35e3f, 4e4f, 45e3f, 5e4f,
78 6e4f, 8e4f, 15e4f, 25e4f, 5e5f, 1e7f};

◆ subdiv_eta

const std::size_t subdiv_eta {5}

Definition at line 81 of file dumpNPs.cxx.

81{5};

◆ subdiv_pt

const std::size_t subdiv_pt {3}

Definition at line 82 of file dumpNPs.cxx.

82{3};