ATLAS Offline Software
Loading...
Searching...
No Matches
CalibrationDataInterfaceROOT.cxx File Reference
#include "CalibrationDataInterface/CalibrationDataInterfaceROOT.h"
#include "CalibrationDataInterface/CalibrationDataContainer.h"
#include "CalibrationDataInterface/CalibrationDataEigenVariations.h"
#include "CalibrationDataInterface/CalibrationDataInternals.h"
#include <CxxUtils/StringUtils.h>
#include "TMath.h"
#include "TEnv.h"
#include "TFile.h"
#include "TObjString.h"
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cassert>
#include <cstring>

Go to the source code of this file.

Typedefs

typedef std::pair< double, double > UncertaintyResult
 The following typedef is for convenience: most uncertainties can be asymmetric.

Functions

 ClassImp (Analysis::CalibrationDataInterfaceROOT) Analysis
std::vector< std::string > split (const std::string &str, const char token=';')
 local utility function: split string into a vector of substrings separated by a specified separator, and with whitespace in the results trimmed
std::string_view trimWhiteSpaces (std::string_view str) noexcept
 Removes all trailing and starting whitespaces from a string.

Typedef Documentation

◆ UncertaintyResult

typedef std::pair<double, double> Analysis::UncertaintyResult

The following typedef is for convenience: most uncertainties can be asymmetric.

The pair holds the positive (first) and negative (second) uncertainties. Note that in the context of systematic uncertainties, "positive" and "negative" may reflect what happens if the uncertainty parameter is varied. This means that the "positive" uncertainty result may be negative etc.

Definition at line 33 of file CalibrationDataContainer.h.

Function Documentation

◆ ClassImp()

Definition at line 289 of file CalibrationDataInterfaceROOT.cxx.

293 :
294 m_runEigenVectorMethod(false), m_EVStrategy(SFEigen), m_useRecommendedEVExclusions(false), m_verbose(true),
295 m_absEtaStrategy(GiveUp), m_otherStrategy(Flag)
296{
297 // Normal constructor.
298 //
299 // taggerName: this should correspond to the tagger name as used in the calibration ROOT file
300 // configname: full name of the configuration file
301 // pathname: directory specification for separate scale factor or efficiency ROOT file
302
303 m_taggerName = taggerName;
304
305 TEnv env;
306 env.ReadFile(configname.c_str(),kEnvGlobal);
307
308
309 // ROOT file containing the calibrations
310 TString filename = env.GetValue("File", "BTaggingPerformanceCalibrations.root");
311 m_filenameEff = string(env.GetValue("FileEff", "")); m_filenameEff = trimWhiteSpaces(m_filenameEff);
312 m_filenameSF = string(env.GetValue("FileSF", "")); m_filenameSF = trimWhiteSpaces(m_filenameSF);
313 if (m_filenameEff == "") {
314 m_filenameEff = pathname + filename.Data();
315 }
316 if (m_filenameSF == "") {
317 m_filenameSF = pathname + filename.Data();
318 }
319
320 if (m_verbose) {
321 cout << "=== CalibrationDataInterfaceROOT::CalibrationDataInterfaceROOT ===" << endl;
322 cout << " Config name : " << configname << endl;
323 cout << " taggerName : " << taggerName << endl;
324 cout << " Efficiency file name : " << m_filenameEff << endl
325 << " SF file name : " << m_filenameSF << endl;
326 }
327
328 m_fileEff = TFile::Open(m_filenameEff.c_str(), "READ");
329 if (m_filenameEff == m_filenameSF)
330 m_fileSF = m_fileEff;
331 else
332 m_fileSF = TFile::Open(m_filenameSF.c_str(), "READ");
333
334 if (m_verbose) {
335 TObjString* s;
336 m_fileSF->GetObject("VersionInfo/BuildNumber", s);
337 if (s) cout << " CDI file build number: " << s->GetName() << endl;
338 cout << endl;
339 }
340
341 m_flavours = { "B", "C", "T", "Light" };
342 string testPrefix(taggerName); testPrefix += ".";
343
344 // Since TEnv doesn't allow for straight retrieval of vectors of strings, expect
345 // semicolon-separated entries (semicolon because ROOT considers this as a "special"
346 // token anyway in object names).
347 string::size_type end;
348
349 // Calibration names for the efficiencies
350 std::map<string, std::vector<string> > effNames;
351 for (auto const& flavour : m_flavours) {
352 string test(testPrefix); test += "EfficiencyCalibration"; test += flavour; test += "Name";
353 effNames[flavour] = split(string(env.GetValue(test.c_str(), "default")));
354 }
355 setEffCalibrationNames(effNames);
356
357 // Calibration names for the efficiency scale factors
358 std::map<string, string> SFNames;
359 for (auto const& flavour : m_flavours) {
360 string test(testPrefix); test += "ScaleFactorCalibration"; test += flavour; test += "Name";
361 SFNames[flavour] = string(env.GetValue(test.c_str(), "default"));
362 SFNames[flavour] = trimWhiteSpaces(SFNames[flavour]);
363 }
364 setSFCalibrationNames(SFNames);
365
366 // Since TEnv doesn't allow for straight retrieval of vectors of strings, expect
367 // semicolon-separated entries (semicolon because ROOT considers this as a "special"
368 // token anyway in object names).
369 // Don't prefix this since the aliases are common to all taggers (even if they are read again for each tagger).
370 string AL(env.GetValue("aliases", ""));
371 if (AL.size() > 0) {
372 do {
373 end = AL.find(";");
374 string alias = AL.substr(0, end);
375 // Each alias specification uses an arrow ("->"). Forget about entries
376 // not properly following this specification.
377 // NB: TEnv imposes a maximum string length of 1024 characters -- is this a problem?
378 string::size_type arrow = alias.find("->");
379 if (arrow == string::npos) continue;
380 string target = alias.substr(0,arrow); target = trimWhiteSpaces(target);
381 m_aliases[target] = alias.substr(arrow+2);
382 m_aliases[target] = trimWhiteSpaces(m_aliases[target]);
383 if (end != string::npos) AL = AL.substr(end+1);
384 } while (end != string::npos);
385 }
386
387 //run egenvector method or not?
388 string test="runEigenVectorMethod";
389 m_runEigenVectorMethod=(bool)env.GetValue(test.c_str(),0);
390
391 if (m_runEigenVectorMethod) {
392 // Retrieve the list of systematic uncertainties not to be considered when building up
393 // the full covariance matrix used for the eigenvector method.
394 // We do this in two steps: first, for backward compatibility reasons, a flavour-independent list is scanned.
395 // Second, flavour-specific lists are scanned.
396 test = "excludeFromCovMatrix";
397 std::vector<std::string> to_exclude = split(env.GetValue(test.c_str(), ""));
398 // Copy the resulting list to all flavours
399 for (auto const& flavour : m_flavours) {
400 m_excludeFromCovMatrix[flavour] = to_exclude;
401 }
402 for (auto const& flavour : m_flavours) {
403 test = "excludeFrom"; test += flavour; test += "CovMatrix";
404 to_exclude = split(env.GetValue(test.c_str(), ""));
405 // Append to the existing list
406 m_excludeFromCovMatrix[flavour].insert(m_excludeFromCovMatrix[flavour].end(), to_exclude.begin(), to_exclude.end());
407 }
408
409 unsigned int n_excluded = 0;
410 for (auto const& flavour : m_flavours) {
411 n_excluded += m_excludeFromCovMatrix[flavour].size();
412 }
413 if (m_verbose) {
414 cout << " List of uncertainties to exclude:";
415 if (n_excluded == 0) cout << " none";
416 for (auto const& flavour : m_flavours) {
417 if (m_excludeFromCovMatrix[flavour].size() > 0) {
418 cout << "\n\t" << flavour << ":\t";
419 for (unsigned int i = 0; i < m_excludeFromCovMatrix[flavour].size(); ++i) {
420 cout << m_excludeFromCovMatrix[flavour].at(i);
421 if (i+1 == m_excludeFromCovMatrix[flavour].size()) cout << "; ";
422 }
423 cout << endl;
424 }
425 }
426 cout << endl;
427 }
428
429 // The following determines whether also pre-determined (recommended) lists of uncertainties are to be excluded from EV decomposition.
430 // These lists are stored with the CalibrationDataContainers, which have not been instantiated yet (so we cannot show them at this point).
431 m_useRecommendedEVExclusions = (bool) env.GetValue("ExcludeRecommendedFromEigenVectorTreatment", false);
432
433 // determine also the eigenvector reduction strategies
434 std::map<string, EVReductionStrategy> mappings;
435 mappings["Loose"] = Loose;
436 mappings["Medium"] = Medium;
437 mappings["Tight"] = Tight;
438 for (auto const& flavour : m_flavours) {
439 test = testPrefix; test += "EigenvectorReduction"; test += flavour;
440 std::string reduction = string(env.GetValue(test.c_str(), "Loose"));
441 reduction = trimWhiteSpaces(reduction);
442 m_EVReductions[flavour] = mappings.find(reduction) == mappings.end() ? mappings["Loose"] : mappings.find(reduction)->second;
443 }
444 }
445
446 // determine |eta| validity range
447 m_maxAbsEta = env.GetValue("MaxAbsEta", 2.5);
448 if (m_maxAbsEta < 0) m_maxAbsEta = 2.5;
449
450 // set validation / protection strategy in case an out-of-bounds eta value is specified
451 string strategy = string(env.GetValue("OutOfBoundsEta", "GiveUp"));
452 strategy = trimWhiteSpaces(strategy);
453 if (strategy == "GiveUp") m_absEtaStrategy = GiveUp;
454 else if (strategy == "Flag") m_absEtaStrategy = Flag;
455 else if (strategy == "Ignore") m_absEtaStrategy = Ignore;
456 else {
457 cerr << "unknown |eta| extrapolation strategy: " << strategy << ", setting to GiveUp" << endl;
458 m_absEtaStrategy = GiveUp;
459 }
460
461 // set validation / protection strategy in case out-of-bounds variables are specified
462 strategy = string(env.GetValue("OutOfBoundsOther", "Flag"));
463 strategy = trimWhiteSpaces(strategy);
464 if (strategy == "GiveUp") m_otherStrategy = GiveUp;
465 else if (strategy == "GiveUpExtrapolated") m_otherStrategy = GiveUpExtrapolated;
466 else if (strategy == "Flag") m_otherStrategy = Flag;
467 else if (strategy == "Ignore") m_otherStrategy = Ignore;
468 else {
469 cerr << "unknown general extrapolation strategy: " << strategy << ", setting to Flag" << endl;
470 m_otherStrategy = Flag;
471 }
472
473 // maximum tag weight to accept
474 m_maxTagWeight = env.GetValue("MaxTagWeight", 10.0);
475
476 // MC/MC (hadronisation) scale factors: making this user-steerable is intended to be *temporary* only
477 m_useMCMCSF = (bool) env.GetValue("useMCMCSF", 1);
478 // MC/MC (topology) scale factors: making this user-steerable is intended to be *temporary* only
479 m_useTopologyRescaling = (bool) env.GetValue("useTopologySF", 0);
480
481 if (m_verbose) cout << "======= end of CalibrationDataInterfaceROOT instantiation ========" << endl;
482}
std::string_view trimWhiteSpaces(std::string_view str) noexcept
Removes all trailing and starting whitespaces from a string.
std::vector< std::string > split(const std::string &str, const char token=';')
local utility function: split string into a vector of substrings separated by a specified separator,...
size_t size() const
Number of registered mappings.
setBGCode setTAP setLVL2ErrorBits bool

◆ split()

std::vector< std::string > Analysis::CalibrationDataInterface::split ( const std::string & str,
const char token = ';' )

local utility function: split string into a vector of substrings separated by a specified separator, and with whitespace in the results trimmed

Definition at line 9 of file CalibrationDataInternals.cxx.

9 {
10 std::vector<std::string> result = CxxUtils::tokenize(str, token);
11 for (std::string& element : result) {
12 element = CxxUtils::trimWhiteSpaces(element);
13 }
14 return result;
15 }
std::string_view trimWhiteSpaces(std::string_view str) noexcept
Removes all trailing and starting whitespaces from a string.
std::vector< std::string > tokenize(std::string_view the_str, std::string_view delimiters)
Splits the string into smaller substrings.

◆ trimWhiteSpaces()

std::string_view CxxUtils::trimWhiteSpaces ( std::string_view str)
noexcept

Removes all trailing and starting whitespaces from a string.

Definition at line 27 of file Control/CxxUtils/Root/StringUtils.cxx.

27 {
28 auto is_not_space = [](unsigned char c) { return !std::isspace(c); };
29
30 auto start = std::find_if(str.begin(), str.end(), is_not_space);
31 auto end = std::find_if(str.rbegin(), str.rend(), is_not_space).base();
32
33 return (start < end) ? std::string_view(start, end) : std::string_view{};
34 }
STL namespace.